web-dev-qa-db-ja.com

バイナリモードとテキストモードで書き込まれたファイルの違い

バイナリモードでは発生せず、テキストモードで開かれたファイルに書き込む場合、どのような変換が行われますか?特にMS Visual Cで。

unsigned char buffer[256];
for (int i = 0; i < 256; i++) buffer[i]=i;
int size  = 1;
int count = 256;

バイナリモード:

FILE *fp_binary = fopen(filename, "wb");
fwrite(buffer, size, count, fp_binary);

対テキストモード:

FILE *fp_text = fopen(filename, "wt");
fwrite(buffer, size, count, fp_text);
54
jholl

ほとんどのプラットフォームは、ストリームを処理するときに「t」オプションまたは「text-mode」オプションを無視すると思います。ただし、Windowsではこれは当てはまりません。 [〜#〜] msdn [〜#〜] でfopen()関数の説明を見ると、「t」オプションを指定すると次のような効果があることがわかります:

  • 改行( '\ n')は、出力時に '\ r\n "シーケンスに変換されます
  • キャリッジリターン/ラインフィードシーケンスは、入力時にラインフィードに変換されます。
  • ファイルが追加モードで開かれると、ファイルの終わりでctrl-z文字(文字26)が検査され、可能であればその文字が削除されます。また、その文字の存在をファイルの終わりと解釈します。これは、CPMの時代(3世代目または4世代目までの子供たちに訪問されている親の罪についての何か)からの不幸なホールドオーバーです。前述の意見とは異なり、ctrl-z文字は追加されません。
45
Jon Trauntvein

テキストモードでは、改行「\ n」はキャリッジリターン+改行「\ r\n」に変換される場合があります

通常は、バイナリモードで開きます。テキストモードでバイナリデータを読み取ろうとしても機能せず、破損します。ただし、バイナリモードでも問題なくテキストを読み取ることができます。「\ n」から「\ r\n」への自動変換は行われません。

fopen を参照

27
MrZebra

さらに、「rt」でファイルを開くと、Ctrl-Z文字で入力が終了します。

5
SmacL

もう1つの違いは、fseekを使用する場合です。

ストリームがバイナリモードで開かれている場合、新しい位置は、OriginがSEEK_SETの場合はファイルの先頭から、OriginがSEEK_CURの場合は現在のファイル位置から、OriginがSEEK_ENDの場合はファイルの最後から測定された正確なオフセットバイトです。一部のバイナリストリームは、SEEK_ENDをサポートしない場合があります。

ストリームがテキストモードで開いている場合、オフセットでサポートされる値はゼロ(すべてのOriginで機能します)と同じファイルに関連付けられたストリームでstd :: ftellへの以前の呼び出しによって返された値(のみで機能します) SEEK_SETの起源。

4
Ming

ファイルに改行文字が混在しているテキストモードでファイルを開くと、興味深い問題が発生しました。

1\n\r
2\n\r
3\n
4\n\r
5\n\r

私たちの要件は、現在の位置をファイルに保存し(fgetposを使用)、ファイルを閉じてから、ファイルを再度開いてその位置にシークできる(fsetposを使用)ことです。

ただし、ファイルの行末が混在している場合、このプロセスは実際の同じ位置へのシークに失敗しました。私たちの場合(私たちのツールはC++を解析します)、すでに見たファイルの一部を再読み込みしていました。

バイナリを使用してください。そうすれば、ファイルの読み取りと書き込みを正確に制御できます。

3
Richard Corden