计算机中文件的类别
从最本质上说,所有计算机中存储的信息都是二进制格式,无论是一个jpg图片,一个exe程序,一个mp4视频或者一个txt文档等等,对计算机而言,他们在硬盘上存的就是一堆儿一堆儿的01010011…的序列,以上所提到的不同类型的文件在硬盘上都是按0和1存储,不同点仅在于用了多少个0和1而已。
为何要区分文本文件和二进制文件
私以为,文本文件最初出现时是为了人类方便阅读而设计的,也就是人为设计一种格式来解释0和1的组合如何被计算机所“解释”,这种解释规范就是字符集编码,例如ASCII码,UTF-8码,当计算机按照这个编码规则去读取文件的时候,读出来的就是一个一个的字符。
例如,用ASCII码规则去解释如下组合
二进制 01000001 01000010 01000011 01000100
十六进制 0x41 0x42 0x43 0x44
字符 A B C D
解释出来就是“ABCD”四个字母,在文本编辑器或者控制台上都显示为ABCD。
如果不按照ASCII码去解读,它就是一个二进制文件,读出来的就是
0x41 0x42 0x43 0x44,至于这四个数到底表示什么含义,要根据文件的类型来解释,如果是jpg文件,它可能表示一个格式信息或者一个像素点的RGB值,如果是一个exe文件,它可能表示一个中间变量的运算结果,这就取决于用何种程序来读取并解释这段信息了,这就是为什么我们用视频播放器去打开exe文件会发现是乱码或者直接报错,因为没有用对解释规则,这段数据头部都不是mp4规定的头部格式,若用视频播放器去读取一定会出错。同样的道理,用视频播放器剪辑一个视频并保存后,那么这段mp4视频的文件格式一定是包含标准mp4文件的一些格式信息的,若你用另一个vlc播放器去读取也会得到一堆乱码,因为文件格式不符合vlc。
二进制文件又称为流式文件,就是一个数据流,不同的程序采用不同的解释规则来处理这个数据流,数据流可以是任意长度的,文本文件每一个字节代表一个字符,属于流式文件的特例。
存储方式的不同
这里可能会有读者有疑惑,不是前文已经说了吗,所有的信息都是以二进制方式存储的,不区分文件类别的啊。是的,确实是这样,你没有错,问题的根本在于这些二进制数我们如何去解释,请体会这句话,阅读数遍以上,首先我们制定一个解释规则(例如ASCII码表),用这个解释规则来生成数据并存储起来,当我们再以这个规则去读取数据的时候,我们就能看到“原始”的数据含义。人类最伟大的发明莫过于文字,所以对于文字的处理在计算机的发展中是非常重要的研究方向,以至于我们专门为存储和表示文字而去规定了一套规则(ASCII码表),甚至后期为了能让世界上各个语言的人种共享计算机的便利,发明了一套集大成的规则(UTF-8码表),如果我们在存储数据的时候就下意思地按照这套规则来存储,那么储存好的文件我们就叫它文本文件(也有一种说法叫文字文件,更为形象),文本文件是如此重要,以至于我们把它单独拿了出来,重点关注,而把其他的图片或者视频程序之类的统称为二进制文件,因为他们也有对应的编码规范,但是实在太多了,不像文字统一性这么好,如果都去重点关注,那会累死人的,所以干脆都叫二进制文件。
所以总结以下,二进制文件的范围是涵盖文本文件的,只是因为文本对于我们人类来说实在太重要了,为了突出这种重要性,在存储数据的时候刻意让数据符合我们制定的文字规范存储,当我们用这种规范再去读取的数据的时候就知道它原本的含义。
举个例子
以最简单的txt文件为例,你在Windows系统下,当你在一个txt文件中写入这样一行字符“hello world”,第二行写“hi man”,你把他保存起来,放到桌面上,起名字叫“new.txt”,那么它在计算机中是这样存放的
hello world\r\n
hi man
其中\r\n表示一行的结束,是作为一个行结束符号,如果我们把这个字符串显示到终端中,显示程序读取到这个结束符的时候就自动换行,重新开始一行进行显示,因为控制符号是不显示的,所以最终呈现出来的效果就是
hello world
hi man
但是如果以二进制的形式去读取的话,例如我们用一些数据恢复软件,或者winhex,hexdump软件的话,他们是不区分文本模式的,全部按照二进制形式处理,读出来的就会是
0x68 0x65 0x6c 0x6c 0x6f 0x20 0x77 0x6f 0x72 0x6c 0x64 0x0d 0x0a
0x68 0x69 0x20 0x6d 0x61 0x6e
注意,黄色是不显示的,他们是格式控制字符。
注意事项
需要注意的是,任何文本文件,其存储的值都会在0-127的范围内,这个范围涵盖了格式控制符(一般不会在终端上显示出来,但在文件中存在,作为指导程序的“指示”存在,指导程序如何控制显示格式)和字母,数字,特殊字符。因为ASCII码表规定好了,就是用这个范围的数字来表示字母,数字,符号和格式控制符,如果程序以文本的格式去读的话,例如你声明了一个char变量,但是却读到了0x80(128dec),那一定会报错的,但是如果你声明的不是char变量,而是int变量,那程序就会认为这就是一个数值,没有错。