开门见山亮出重点:一切文件都是二进制文件
为什么这么说,因为文件一般都是存储在磁盘介质上的,从磁盘的角度看存储都是010101这样的二进制级别的东西,不存在说是有文本直接存到磁盘上,所以可以说文本文件只是上层的表现形式,最终的文件形式都是二进制的。
但是,我们可以考虑这样一个情况,如果一个文件里边的所有0101序列可以根据字符编码翻译成字符序列(包括可打印的字符以及空白字符等),这个文件是不是比较特殊一些呢,它看似意义更直白一些,因为翻译一下就成了全是文本内容的文件,这样的文件我们可以称之为“文本文件”。下边举个例子:
- 二进制序列1(十六进制表示):/x10/x11/x12/x13
- 二进制序列2(十六进制表示):/x30/x31/x32/x33
对于序列1来说我们无法翻译成有效的可表示字符序列,而对于序列2来说我们根据编码规则可以翻译成序列“0123”
上边是从介质存储角度分析,现在我们顺着数据流动的方向倒着往上层走,到了系统提供的有关文件操作的系统调用,不管上层是什么程序,我们最终是通过这些系统调用来进行文件操作的,下面看一下两种系统下的接口:
1、Windows系统下文件操作函数
HANDLE WINAPI CreateFile(
__in LPCTSTR lpFileName,
__in DWORD dwDesiredAccess,
__in DWORD dwShareMode,
__in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes,
__in DWORD dwCreationDisposition,
__in DWORD dwFlagsAndAttributes,
__in_opt HANDLE hTemplateFile
);
2、POSIX系统下文件操作函数
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
int creat(const char *pathname, mode_t mode);
仔细研究一下上边的接口函数我们会发现这些文件操作的系统调用函数并没有有关“文本”或者“二进制”模式相关的选项,也就是说在系统调用这一层面是不分文本模式和二进制模式的。
我们接着继续往上层走,下面从编程语言角度来分析一下这个问题,在C ,C++ ,Python等语言中都提供文件操作的库,利用这些库我们可以很方便的对文件进行读写操作,而利用这些库函数进行文件操作时都会有一些共同点,就是选择以什么模式进行读写文件,即:二进制模式or文本模式。可以发现终于出现这两种模式了,为什么会出现这样两种模式呢?下边提到的两个问题跟这个有关:1、换行符问题2、数字表示与存储
不同的操作系统系统换行符可能表示不一样,这是针对文本模式来说的,二进制模式下是不存在这个问题的,比如说:Windows系统/r/n被处理成换行,而Linux系统/n被处理成换行符,为了提高可移植性编程语言级别会对这种不同进行替换从而达到屏蔽作用。
数字存储如果采用二进制模式采取的方法就是直接将内存中的数写入磁盘,而采用文本模式的话就必须将数字转换成数字字符然后再写入磁盘,多了一个“转换”的过程。例如:5678这个数二进制模式下存储为00010110 00101110 (两个字节)而在文本模式下则存储为00110101 00110110 00110111 00111000 (四个字节)