链接:https://www.zhihu.com/question/19971994/answer/570107874
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
回答较长,但是保证有趣。( • ̀ω•́ )✧
这要从文件的本质开始说起,首先,我们用一个简单的例子来演示一下计算机处理文件的过程。
提到计算机,很多人都知道二进制,二进制具体是用来干嘛的呢?是用来保存和表示信息的,计算机里所有的信息,无论是CPU正在执行的指令还是你保存在硬盘里的小姐姐,归根结底都是像下面这样的01序列:
0100100001100101011011000110110001101111
但是当看到这样的序列,不要说一般的电脑使用者,就是程序员也不可能很快地认出这是什么。实际应用中,对于这样的二进制序列,我们往往会做如下处理:
- 以4位为一组,将序列分成若干组。对于上面的序列,分割之后如下:
0100 1000 0110 0101 0110 1100 0110 1100 0110 1111
2. 现在我们可以把这些二进制序列看做是10个二进制数,每个数有4位。之后我们把这10个数转换成16进制。转换之后如下:
4 8 6 5 6 c 6 c 6 f
因为4位的二进制数所能表示的最大的16进制数也就只有f,所以这样得到的16进制数可以保证只有1位,现在我们得到了10个16进制的数字,而且每个只有1位,看起来是不是清爽多了?
截止到现在为止,我们所做的工作对于任意格式的文件来说都是通用的,下面假设这个文件是个文本文件,我们来手动解析这个文本文件。
3. 将10个16进制数字强行合并成2位的16进制数,如下:
48 65 6c 6c 6f
4. 现在,我们得到了5个2位的16进制数,将他们转换为10进制(其实在这里也可以不做转换,转换成10进制只是为了符合我们的习惯)
72 101 108 108 111
5. 现在,我们得到了5个无比亲切的10进制数,上过小学甚至是幼儿园的孩子都可以大声地把这5个数字读出来。然后,我们搬出一件驰名中外的东西——ASCII码表.
![](https://img2020.cnblogs.com/blog/1209802/202104/1209802-20210408084634371-1912505831.png)
链接:https://www.zhihu.com/question/19971994/answer/570107874
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
当我们对照ASCII码表把上面的5个数字翻译出来后,我们终于得到了一个语文老师也能够看懂的单词
Hello
把上面的过程稍作简化,从4位二进制数直接向ASCII码表对应的字符翻译,就可以大致认为是计算机读取文本文件的原理,实际上,由于ASCII字符集能表示的字符已经远远无法满足人们的使用,现在使用的往往是诸如Unicode这样的大型字符集,但是基本原理和使用ASCII字符集别无二致,只是能表示的字符多了一些,需要的二进制位长了一些。
有些优秀的同学可能会问,那我第5步的时候为什么就一定要用ASCII码表或者Unicode表来查,而不是别的什么表呢?这个问题就引出了文件类型的概念。当你打开一个扩展名为txt的文件,或者虽然扩展名不是txt,但是你使用文本编辑器强行打开时,文本编辑器就会认为这是一个文本文件,然后使用文本文件对应的规则来“翻译”这些二进制序列。
可想而知,如果这个文件确实是文本文件,那么解析出来就是人类可以看懂的信息,如果这个文件本来就不是一个文本文件,那么强行解析出来就会变成杂乱无章的字符组合,这样的字符组合就有一个为人们熟知的名字——乱码。
比如我把上面举例用的字符串在16进制编辑模式下随意改为123456789a
,使用记事本打开就是这样的:
![](https://img2020.cnblogs.com/blog/1209802/202104/1209802-20210408084648843-2040584846.png)
链接:https://www.zhihu.com/question/19971994/answer/570107874
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
这就好比美国人对一个不懂英语的中国人说:Good morning!,中国人按照中文的发音去理解英语,听到的就是“孤的猫宁”,孤的猫宁是什么意思?总之不是它原来的意思。
同样,对于其他类型的文件,比如音频、图片、视频,计算机会用不同的解码方式去解读他们包含的二进制序列,虽然乍一看都是0101,但是因为“翻译”方式的不同,他们就可以表示不同类型的信息。文件之所以要加扩展名,就是为了让计算机能够知道,在读取这个文件的时候应该使用哪本“字典”来进行翻译,这样才能够呈现出它本来的信息。
回到题主的问题,其实在编程的概念里,只要是使用文本编辑器打开可以展现出人类可读(human-readable)的信息的文件,都可以算作宽泛的文本文件,如txt,html,css,java,xml等等,这些文件的编码都符合某种文字编码规范,如上文提到的ASCII、Unicode、还有以前中文中经常使用的GB2312;反之,如果文件的编码不符合任意一种文字编码规范,使用文本编辑器打开只能看到乱码,就可以认为它属于二进制文件。要想打开二进制文件,就必须要知道该文件所对应的编码规范,有些二进制文件使用通用的规范进行编码,比如常见的图片格式JPEG,音频格式MPEG-3,视频格式MPEG-4,而有些二进制文件的编码格式只有程序的开发者自己清楚,这样的文件对于普通的用户来说就几乎是保密的。