文件访问中的文本模式和二进制模式有什么区别吗?

8

如果我以文本模式而非二进制模式打开文件,是否有区别?因为我读到UNIX和Linux不区分文本和二进制文件。


4
对于Unix来说,没有区别。(文本和二进制只是微软的产物) - wildplasser
1
据我所知,它不仅符合C99标准规范。 - Basile Starynkevitch
2
并非所有“文本”文件都可以使用CR / LF转换正确读取;只有那些以ASCII(或接近衍生或扩展)编码的文件才能够。可以说,使用EBCDIC编码的文本文件也是“文本文件”,因此至少需要对所使用的编码进行一些定义。此外,CR / LF转换可能会破坏16位Unicode文本文件。可以说,单独的“文本模式”已经过时了。 - Jongware
1
@wlidplasser:我认为一些旧版本的MacOS也关心二进制和文本?(但我不了解MacOS9) - Basile Starynkevitch
1
我还记得苹果曾经使用\n\r或者仅使用\r作为换行符。 - wildplasser
2
IIR,二进制模式和文本模式中某些系统的另一个差异是“EOF”。在文本模式下,“'^Z'”不会被读取为一个char,但会触发“EOF”条件。写入文件并关闭文件时将应用“'^Z'”。即使有一些旧系统会基于文本/二进制模式区分行缓冲,但我怀疑它是否符合C标准。许多操作系统确实进行了区分(仍在进行中?)。如果您希望您的代码与非*nix系统不兼容,请忽略文本/二进制设置。 - chux - Reinstate Monica
1个回答

6
在Linux上(至少在像Ext4这样的本地文件系统和大多数其他文件系统上,使用通常的GNU libc),没有区别。
也许有些奇怪的文件系统可以有一个特定的标志来以不同方式打开二进制或文本文件。我不知道这样的文件系统。也许你可以编写一些FUSE文件系统来区分它们,也许还要在奇怪的自定义libc中对fopen进行一些额外的hack。
然而,C99标准(至少是n1256草案的第271页,§7.19.5.3)明确提到了文本与二进制模式,因此如果符合标准,您的程序将更容易移植到其他系统(如Windows)。
所以我的观点是,您可能想尝试传递一个模式字符串给fopen,以区分二进制模式和文本模式。(我同意我并不经常这样做)。这不会有害。
Linux fopen(3)手册明确说明:

模式字符串还可以包括字母“b”,作为最后一个字符,或作为任何两个字符字符串中的字符之间的字符。这仅是为了与C89兼容,没有任何影响;在包括Linux在内的所有符合POSIX的系统上都会忽略“b”。(其他系统可能会对文本文件和二进制文件进行不同的处理,如果您进行对二进制文件的I/O并期望您的程序可能被移植到非UNIX环境中,则添加“b”可能是个好主意)

当然,open(2)调用没有传输模式标志的方式。(你可能需要一些私有的ioctl(2)


3
这里文件系统不相关,文件系统在块级别操作。CR / LF (如果有的话) 的翻译/解释在libc层面上完成(例如:getc,fgets,fread,fseek (!),ftell(!),...)。 - wildplasser
原则上你是对的,但我猜一些FUSE文件系统可能会以不同的方式处理,例如将\r\n转换为\n....! - Basile Starynkevitch
我不了解FUSE文件系统。[我觉得我不想知道它。用火烧掉它...] - wildplasser
啊哈,如果我没记错的话,那个以前被称为循环FS。 - wildplasser

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接