为什么 fwrite() 不使用 C 语言中的“wb”在 Mac OS X 上写入二进制文件?
为了学习 C 并理解二进制文件和文本文件之间的区别,我尝试将字符串作为两种文件类型写入文件,如下所示:
char * string = "I am a string!";
FILE * filePtrA = fopen("/output.txt", "wt");
fwrite(string, strlen(string), 1, filePtrA);
FILE * filePtrB = fopen("/output.bin", "wb");
fwrite(string, strlen(string), 1, filePtrB);
fclose(filePtrA);
fclose(filePtrB);
但是 "wt"
和 “wb”
正在写入为文本文件,其中 “wb”
应该写入为二进制文件。对于这两个文件来说,十六进制看起来都是这样:
49 20 61 6D 20 61 20 73 74 72 69 6E 67 21
为什么会发生这种情况,以及如何将某些内容写入二进制文件?
我读到操作系统(Mac OS X 10.6 - GCC 4.2)可能无法区分二进制文件和文本文件,尽管我仍然困惑为什么十六进制编辑器无法检测到任何差异。
For the sake of learning C and understanding the difference between Binary Files and Text Files, I'm attempting to write a string to file as both file types like so:
char * string = "I am a string!";
FILE * filePtrA = fopen("/output.txt", "wt");
fwrite(string, strlen(string), 1, filePtrA);
FILE * filePtrB = fopen("/output.bin", "wb");
fwrite(string, strlen(string), 1, filePtrB);
fclose(filePtrA);
fclose(filePtrB);
However both "wt"
and "wb"
are writing as a Text File, where "wb"
should be writing as a Binary File. Hex appears like so for both files:
49 20 61 6D 20 61 20 73 74 72 69 6E 67 21
Why is this happening, and how can I write something as a Binary File?
I have read that the OS (Mac OS X 10.6 - GCC 4.2) might not differentiate between Binary and Text Files, though I'm still stumped why a hex editor wouldn't detect any difference.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
所有文件都是二进制的。
fopen
上下文中“文本文件”和“二进制文件”之间的区别在于,标准库可能会在文本模式下使用过滤器来读取和写入文件。在二进制模式下,你所写的始终是所写的。我知道的唯一实际例子是在 Windows 中,在文本模式下打开文件将使其在 Windows 样式行结尾(CRLF,
"\r\n"
)和 C 样式/之间进行转换Unix 风格的行结束符(LF,"\n"
)。例如,当您在 Windows 中以文本模式打开文件进行读取时,行结尾将在程序中显示为"\n"
。如果您以二进制模式打开它,则行结尾将在程序中显示为"\r\n"
。您还可以使用
cat
检查文件,例如:你应该得到输出:
I am a string!
All files are binary.
The difference between "text files" and "binary files" in the context of
fopen
is that the standard library may use a filter for reading and writing the file when in text mode. In binary mode, what you write is always what is written.The only practical example I know of is in Windows, where opening a file in text mode will make it convert between Windows-style line endings (CRLF,
"\r\n"
) and C-style/Unix-style line-endings (LF,"\n"
). For example when you open a file for reading in Windows in text mode, line endings will appear as"\n"
in your program. If you were to open it in binary mode, line endings would appear as"\r\n"
in your program.You can also inspect your file with
cat
, for example:You should get the output:
I am a string!
这两个文件都是二进制文件。它们是您发送到
fwrite
的数据的精确副本。一些损坏的操作系统具有非二进制的文本文件;它们有额外的垃圾,例如\r\n
替换\n
,或固定大小的行记录等。POSIX 禁止所有这些。在任何 POSIX 操作系统上,文本和二进制模式都是相同的。顺便说一下,
"wt"
不是fopen
的有效模式参数。默认为文本模式。用于请求文本模式的t
修饰符是损坏的 Windows 实现的扩展,其中二进制为默认值,但可根据请求使用文本模式。Both files are binary files. They're an exact copy of the data you sent to
fwrite
. Some broken operating systems have text files which are not binary; they have extra junk like\r\n
replacing\n
, or fixed-size line records, etc. POSIX forbids all of this. On any POSIX OS, text and binary mode are identical.By the way,
"wt"
is not a valid mode argument tofopen
. Text mode is default. Thet
modifier to request text mode is an extension of broken Windows implementations where binary is default but text mode is available by request.文本模式唯一的区别在于它是行结尾。因此,如果您
fprintf
一个\n
,它将根据平台进行翻译。对于您的示例,二进制或文本模式对写入文件的内容没有影响。The only difference text mode makes it to line endings. So, if you
fprintf
a\n
it will be translated according to platform. For your example, binary or text mode makes no difference to what is written to the file.在大多数类 Unix 系统上,以文本模式与二进制模式打开文件没有区别。此外,即使在许多以不同方式处理“文本”和“二进制”文件的系统上,您在上面编写的数据也不会显示出差异。
举例来说,在 Windows 上以文本模式打开文件通常意味着您写入的“\n”将被转换为实际文件中的“\r\n”(在读取过程中会执行相反的操作)。由于您没有写“\n”,因此翻译不会发生。
On most Unix-like systems, there's no difference between opening a file in text vs. binary mode. In addition, the data you're writing above wouldn't show a difference even on many systems that do treat "text" and "binary" files differently.
Just for example, on Windows opening a file in text mode typically means that a "\n" that you write will be translated to "\r\n" in the actual file (and during reading the opposite is done). Since you haven't written a "\n", that translation wouldn't happen.
你说得对。这在类 Unix 系统上并不重要。 来自 cygwin 阵营的讨论。您期望看到什么不同?您正在将 ASCII 文本写入文件,而不是任意二进制数据。
You're right. This doesn't matter on Unix-like systems. Discussion from the cygwin camp. What difference did you expect to see? You are writing ASCII text to a file, not arbitrary binary data.
类似 Unix 的操作系统将两者视为相同。
我不确定这是否是正确的答案,但是如果您想将十六进制文本放入文件中,请尝试在文本之前应用 \x。例如,如果您尝试将 hello 写入文件,则缓冲区将是:
char *buf = "你好";
如果你想将“hello”的十六进制写入文件,你的缓冲区应该像这样
char *buff = "\x68\x65\x6c\x6c\x6f";
希望有帮助
Unix like OS treats both as same.
I'm not sure this is the right answer, but if you want to put a text as hex into a file, try applying \x before the text.e.g. if you are trying to write hello into a file, you're buffer will be:
char *buf = "hello";
If you want to write hex of "hello" into the file, your buffer should be like this
char *buff = "\x68\x65\x6c\x6c\x6f";
Hope it helped