阅读:0

C语言文本流和二进制流

从 C 程序角度来看,无论程序一次读写的是一个字符、字节、文本行还是给定大小的数据区域,作为输入输出的各种文件和设备统一以逻辑数据流的方式展现。C 语言中的数据流可以是文本流或者二进制流,甚至在某些系统上,就连这样的差异也不存在。

通过使用函数 fopen()(或 tmpfile())打开一个文件就会建立一个新的流,直到调用函数 fclose(),该流才会结束。C 语言将文件的管理工作交由运行环境(也就是运行程序的系统)。因此,流是一个传输通道,利用该通道,数据可以从运行环境流入程序中,或从程序流向运行环境。C 语言对设备(例如控制台)的处理机制与对文件的机制是一样的。

每个流都有一个锁机制,当多个线程访问同一个流时,I/O 库函数利用该锁以保证同步性。当对一个流执行读写操作,或者查询和移动流文件位置指示器时,所有流 I/O 函数会首先获得独占访问该流的权限。一旦操作完成,流的权限就会被再次释放,以供其他线程访问。独占流访问权限可以防止“数据竞争”和并发的 I/O 操作。

文本流

文本流用来传输文本中的字符,这里的文本被分割成许多行。文本行都包含一个字符序列,并以换行符作为该序列结尾。文本行也可以为空,也就是说只包含一个换行符。文本最后一行可以有,也可以没有用作结尾的换行符,这由 C 语言的实现版本决定。

C 程序中文本的内部表示方式都是一样的,不受程序运行时所在系统的影响。在给定系统上进行文字输入和输出操作,涉及删除、增加或改变给定的字符。例如,在不是 Unix 内核的操作系统上,在读取文本文件时,行尾修饰符通常必须转换成换行符。

对 Windows 系统而言,行尾修饰符由两个控制字符组成:r(回车)和 n(换行)。类似,在 Windows 平台上,文本流中的控制字符 ^Z(字符码 26),用来表示文本流的结束。

程序员通常不必担心这些系统平台间必要的适应性,因为标准库的 I/O 函数会自动完成转换。然而,如果想确保调用输入函数会生成与之前调用输出函数时同样的文本,那么文本中除了可打印字符以外,只能包含换行符和水平制表符。而且,最后一行应该以一个换行符作为结束,并且任何一行都不能在换行符之前出现空格。

二进制流

二进制流是字节序列,它们不作修改直接传送。也就是说,当操作二进制流时,I/O 函数不会翻译任何控制字符。通过二进制流方式写入文件的数据,在同一个系统中,可以原封不动地读取出来。然而,在有些实现版本中,会在流尾端加上一些值为 0 的字节。

二进制流通常用于编写二进制数据(例如,数据库记录),而不将它转换为文本。如果程序通过二进制流来读取一个文本文件的内容,那么程序中出现的文字就是其存储时的形式,包括所在系统使用的全部控制字符。

在常见的 Unix 系统上,文本流和二进制流之间没有差别。