ifstreamのコンストラクタの引数にオープンモードが指定できます。

例:

ifstream ifs("D:\\test.txt");

ifstream ifs("D:\\test.txt", ios_base::binary);

 ・指定なし ⇒ テキストモード

 ・ios_base::binary ⇒ バイナリモード

 

これって何が違うんでしょうか?


結論から言うと、


テキストモードはOSなどの環境に依存するモードなのです。



そのことをこれから見て行きます。

テキストモードでは、Windowsで言うテキストファイルのような文字列が保存されたファイルを開きます。

もしバイナリファイルをテキストモードで開くと文字化けした意味の無い文字列の塊になるかもしれません。


バイナリモードでは、保存されたデータは文字列とは限りません。

たとえば、intの値がそのまま出力されていたりします。


でも、バイナリのデータとテキストのデータとそれ程区別はなく、

例えば、"あいうえお"といった文字列をバイナリで保存してもテキストで保存しても同じファイルができあがります。

逆にそれをバイナリモードで読み込んでもテキストモードで読み込んでも同じ結果をメモリ上に保存することになります。


では、いったいこの2つのモードの違いは何でしょうか??



【2つの主な違い】

主な違いは、改行コードの読み込み方です。

まず、改行コードは主に3種類あるのはご存知でしょうか?

 ・\r\n (2バイト。windowsの標準。CRLFなどといわれたりします。)

 ・\r  (1バイト。昔のMacの標準。CRなどといわれたりします。)

 ・\n  (1バイト。Linux系の標準。LFなどといわれたりします。)


環境によって標準で使用されるコードが違うんです。

テキストモードではこの違いを吸収するため、windowsでは"\r\n"を"\n"に変換して読み込みます。

また、書き込みのときは逆のことをします。

つまり、"\n"を"\r\n"で出力します。


Linux系だと、"\n"を"\n"で出力します。


そして、バイナリモードだと、あるがままに入出力するのです。

つまり、"\r\n"は"\r\n"のまま読み込みますし、"\n"は"\n"で書き込みます。



このことを知らないと困った事態が起こります。

例えばWEBでファイルのアップロード機能をC言語で実現したとしましょう。

このとき、受け取ったデータをテキストモードで保存するとどうなるでしょう?

なんと、Linux環境だと、アップロードしたファイルの改行コードが\r\nだったとしても、\nで保存されてしまいます。

もしWindows環境だと、アップロードしたファイルの改行コードが\nだったとしても、\r\nで保存されてしまいます。

アップしたファイルと保存されるファイルが違ってしまいます。

改行コードだけですが、そのあとの処理系によっては改行コードを厳密に規定しているものもあるので大問題です。


もしファイルが画像だったら?

もっと深刻です!

画像が壊れてしまうのは想像できると思います。


困っちゃいますよね?爆弾


ですので、モードは慎重に扱ってあげましょう!



参考:

・ファイルのサイズを取得するには?

・ファイルの内容を効率よくstringに入れるには?