文本流和二进制流
我们在写C程序的时候经常会涉及到对流的操作,比如说从标准输入流读取一串字符串,然后通过标准输出流输出显示在屏幕上,这也就是所谓的IO操作。那么流究竟是什么东西?下面首先对流这个概念做一下解释。
一. 流(stream)的概念
计算机有很多外部设备,比如键盘、鼠标、CD-ROM驱动器、硬盘、网络接口、视频适配器等。这些设备都和IO操作有关系,而每种设备都具有不同的特性和操作协议。操作系统负责实现微处理器和和这些外设的通信细节,并向应用开发程序员提供更为简单和统一的IO接口,比如Linux操作系统下的open(),read(),write()等系统调用使我们可以以文件的形式打开并读写一个设备。
ANSI C进一步对IO的概念进行抽象。就C程序而言,所有的IO操作只是简单地从程序移进或者移出字节,这种字节流便被称为流(stream)。程序员只需要关心创建正确的输出字节数据,以及正确的解释从输入读取的字节数据,特定IO设备的细节对程序员是隐藏的。
因此流是一个高度抽象的概念,它将数据的输入和输出看作是数据的流入和流出,这样不管是什么IO设备:显示器、键盘还是硬盘,都被视为同一种东西。都可以作为流的源和目的,对它们的操作,就是数据的流入和流出。
在C语言中流分为两种类型:文本流(text stream)和二进制流(binary stream)。下面分别进行介绍。
二. 文本流
文本流是指在流中流动的数据是以字符的形式出现的。流中的每一个字符对应一个字节,用于存放对应的ASCII码值,因此文本流中的数据可以显示和打印出来,都是用户可以读懂的信息。比如数5678在文本流中的存放形式是:
ASCII码: 00110101 00110110 00110111 00111000
↓ ↓ ↓ ↓
十进制码: 5 6 7 8
一共占用4个字节。
文本流的有些特性在不同的系统中可能不同。其中之一是文本行的最大长度,标准规定至少允许254个字符。另一个可能的不同是文本行的结束方式。例如,在MS-DOS系统中,文本文件约定以一个回车符和一个换行符(也叫行反馈符)结尾,不过UNIX系统只使用一个换行符结尾。文本流中不能包含空字符(即ASCII码中的NULL)。
三. 二进制流
二进制流中的字节将完全根据程序编写它们的形式写入到文件或者设备中,而且完全根据它们从文件或者设备读取的形式读入到程序中。它们并未做任何改变,这种类型的流适于非文本数据,但是如果你不希望IO函数修改文本文件的行末字符,也可以把它用于文本文件。
二进制流中的数据是按照二进制编码的方式来存放文件的。比如数5678的二进制流中的存储形式为:00010110 00101110只占二个字节。二进制数据也可在屏幕上显示, 但其内容无法读懂。
二进制流比文本流更节省空间,且不用对换行符进行转换,这样可以大大加快流的速度,提高效率,二进制流没有行长度的限制,也可以包含空字符(NULL)。因此,对于含有大量数据信息的数字流,可以采用二进制流的方式;对于含有大量字符信息的流,则采用文本流的方式。
文本文件是基于字符编码的文件,基本是定长的,常见的编码有ASCII编码,UNICODE编码等等。二进制文件是基于值编码的文件,变长编码,你可以根据具体应用,指定某个值是什么意思(这样一个过程,可以看作是自定义编码)。