理解'文件编码'的概念

时间:2013-02-23 15:05:21

标签: c++ file encoding

我已经在网上找到了一些东西和SOF解释'文件编码',但我仍然有疑问。文件是一组相关记录,在磁盘上,其内容只存储为'1'和'0'。每次,正在运行的程序想要读入文件或写入文件,该文件被带入RAM并放入正在运行的程序的地址空间(也称为进程)。现在是什么决定了文件中的位(或字节)应该如何解码/编码,读取和显示/写入?

在SOF上有一个解释说明'在存储级别,文件包含一个字节数组。除此之外,您还拥有文本文件的编码层。格式层位于文本文件的编码层之上,或者位于所有其他二进制文件的字节数组之上。我对此很好,但想知道它是否100%正确。

在理解C ++中的文件打开模式时,基本上出现了这个问题。

5 个答案:

答案 0 :(得分:1)

  

现在决定如何解码/编码和读取/显示/写入文件中的位(或字节)是什么?

显然,文件的格式。如果您正在阅读BMP文件,则必须先阅读标题,然后阅读height * width像素数据。如果您正在阅读.txt,请按原样阅读字符。文本文件可以有不同的编码,例如Unicode。

某些格式(如.png)被压缩,这意味着它们的原始数据占用磁盘上文件的内存空间。

根据各种因素选择特定算法。在Windows上,它通常是重要的扩展。在网络中,content type占主导地位。

通常,如果您尝试以其他格式读取文件,通常会出现垃圾。有时可能会强制执行此操作:例如,尝试在文本编辑器中打开.bmp文件。

答案 1 :(得分:1)

所以基本上我们主要是谈论文本文件,对吗?

现在到了这一点:当你的文本编辑器将文件加载到内存中时,从某些信息中推断出它的文件编码(要么你告诉它,要么它在文件的前几个字节中有一个特殊的文件格式标记,或者其他)。然后它是程序本身决定它如何处理原始字节。

例如,如果您告诉文本编辑器以ASCII格式打开文件,它会将每个字节视为单个字符,并且每当遇到数字65作为当前字节时它将显示字符A show等等(因为65是A的ASCII字符代码)。

但是,如果你告诉它打开你的文件为UTF-16,那么它将一次抓取两个字节(好吧,更准确地说,两个八位字节),它将使用这个 - 将“word”称为要查找的数值,例如,当它读取的两个字节对应ç时,它将显示231字符,ç的Unicode字符代码为{{ 1}}。

答案 2 :(得分:1)

让我们看看这是否有帮助......

Unix文件只是一个位数组(1/0),文件中当前的最小位数是8,即1个字节。所有文件交互都在不低于字节级别完成。现在,在大多数系统上,你不必真正关心文件的最大大小。操作系统中仍有一些小的变化,但如果没有最小尺寸小于1 GB,则很少。

文件的编码或格式仅取决于使用它的应用程序。

有许多常见的文件格式,例如“unix ASCII text”和PDF。您将遇到的大多数文件将在网络上的某处提供文档格式规范。例如,'Unix ASCII文本文件'的规范是:

ascii字符的集合,其中每一行以行尾字符结束。行尾字符在c ++中被指定为std :: endl'或引用的“\ n”。 Unix将此字符指定为二进制值 - 012(oct)或00001010。

希望这会有所帮助:)

答案 3 :(得分:1)

确定如何编码/显示内容完全取决于程序的设计者。当然,某些类型的文件有标准 - PDF或JPG文件的内容具有标准格式。 PDF和JPG的定义非常复杂。

当然,文本文件至少有一些标准 - 但如何解释或使用文本文件的内容可能与JPEG一样复杂和混乱 - 唯一的区别是内容是(一些)一种文本,所以你可以在文本编辑器中加载它并尝试理解它。但请参阅下面的“数据库类型应用程序中的文本”示例行。

在C和C ++中,基本上只有一个区别,文件是“二进制”或“文本”(“非二进制”)。区别在于“特殊位”的处理,主要与“结尾”有关 - 文本文件将包含行尾标记或换行符('\n')[更多关于换行符],以及某些操作系统也包含“文件结束标记” - 例如在旧的CP / M中,文件大小为128或256字节的块。因此,如果我们在文本文件中有"Hello, World!\n",那么该文件将是128字节长,剩余的114字节将是“文件结束”标记。大多数现代操作系统以字节为单位跟踪文件大小,因此不需要在文件中包含文件结束标记。但是C支持许多新旧操作系统,因此语言允许这样做。文件结尾通常是CTRL-Z(DOS,Windows等)或CTRL-D(Unix-Linux等)。当C运行时库命中文件结束字符时,它将停止读取并给出错误代码/行为,就像“没有更多文件要读取”一样。

行结尾或换行需要特殊处理,因为它们在文件所在的操作系统中并不总是相同。例如,Windows和DOS使用“回车符,换行符”(CR,LF - CTRL-M,CTRL-J,ASCII 13和10分别)作为行尾。在Unix的各种形式中(例如Linux,MacOS X和BSD),行结尾仅为“换行”(LF,CTRL-J)。在较旧的MacOS中,行结尾仅为“回车”。因此,作为程序员,您不必担心行结束的确切方式,C运行时库将把“本机”行结尾转换为'\n'的标准化行结尾(转换为“换行“或字符值10)。当然,这意味着C运行时库需要知道“如果CR后跟LF,我们应该只给出一个LF字符”。

对于二进制文件,我们真的不希望任何数据转换,因为我们的像素恰好是彼此相邻的值13和10,并不意味着我们希望它合并为单个10字节,对?如果代码读取值26(CTRL-Z)或4(CTRL-D)的字节,我们当然不希望输入停在那里......

现在,如果我有一个包含以下内容的数据库文本文件:

 10 01353-897617 14000 Mats

你可能不知道这意味着什么 - 我的意思是你可能会发现“垫子”是我的名字 - 但它也可能是一些纸板下的东西(也就是“啤酒垫”)或其他东西要走到场上,比如说穆斯林的“祷告垫”。

数字10可以是客户编号,商品编号,“行号”或类似的东西。 01353-896617几乎可以是任何东西 - 也许是我的电话号码[不是没有,但它确实类似于它] - 但它也可能是“制造商部件号”或某些序列号或某些此类号码。 14000?每件商品的价格,库存的单位数量,我的工资[我希望不是!],距我在澳大利亚悉尼的地址的距离[大概,我认为]。

我相信其他人,没有得到任何其他东西可以提出数百个其他答案。

[事实是,除了“电话号码”开头的位(这是一个有效的英国区号)之外,它只是为了这个答案的目的而构成废话 - 重点是解释“只有在描述字段含义的内容时才能理解文本文件中一组字段的含义“]

当然这同样适用于二进制文件,除了通常更难以弄清楚内容是什么,因为缺少分隔符 - 如果你在上面的文本中没有空格和短划线,那么它将是更难以知道属于哪里,对吗?二进制文件中通常没有“空格”和其他类似的东西。这完全取决于某人在某些代码中的描述或定义,或类似的东西。

我希望我在这里的谣言能给你一些想法。

答案 4 :(得分:1)

我认为层次顺序的描述在这里令人困惑。我会认为格式和编码是相关的,但没有紧密联系在一起。让我们试着正式定义它。

文件是一个连续的字节序列。 字节是一个连续的位序列。

符号是一个数据单位。字节是一种符号。还有其他符号不是字节。考虑数字6 - 它是一个符号但不是一个字节。然而,它可以编码为一个字节,通常为00000110(这是6的二进制补码)。

编码将一组符号映射到另一组符号。最常见的是,它从一组非字节符号映射到字节,当应用于整个文件时,它将成为文件编码。二进制补码给出了数值的表示。另一方面,例如,ASCII表示拉丁字母和相关字符的字节。如果您使用ASCII并将其应用于一串文本,请说" Hello,World!",您将得到一个字节序列。如果将此字节序列存储为文件,则会将文件编码为ASCII。

格式描述了一组有效的符号序列。应用于文件的字节时,它是文件格式。一个例子是用于存储光栅图形的BMP文件格式。它指定开头必须有几个字节将文件格式标识为BMP,然后用几个字节来描述图像的大小和深度,依此类推。不是文件格式的格式的示例将是我们如何用英语写入十进制数字。基本格式是一系列数字字符,后跟一个带有更多数字字符的可选小数点。

文本文件

文本文件是一种格式非常简单的文件。它的格式非常简单,因为它没有结构。它立即以字符的某些编码开始,并以最终字符的编码结束。通常没有页眉或页脚或元数据或类似的东西。您只需从头开始将字节解释为字符。

但是你怎么解释文件中的字符?编码所在的位置。如果文件编码为ASCII,则字节01000001表示拉丁字母A.还有更复杂的编码,例如UTF-8。在UTF-8中,字符不一定用单个字节表示。有些人可以,有些人可以。您可以确定要从第一个字节的前几位解释为字符的字节数。

当您在自己喜欢的文本编辑器中打开文件时,它如何知道如何解释字节?那是一个有趣的问题。文本编辑器必须确定文件的编码。它可以尝试以多种方式做到这一点。有时文件名通过其扩展名提供提示(.txt可能至少与ASCII兼容)。有时,文件的第一个字符可以很好地提示编码是什么。但是,大多数文本编辑器都会为您提供指定将文件视为哪种编码的选项。

文本文件可以具有格式。格式通常完全独立于文本的编码。也就是说,格式根本没有描述有效的字节序列。它改为描述有效的字符序列。例如,HTML是用于标记文档的文本文件的格式。它描述了确定文档内容的字符序列(注意:不是字节序列)。例如,它表示字符序列<html>是一个开始标记,必须在某个时候由结束标记</html>跟踪。当然,格式为much more detailed than this

二进制文件

二进制文件是一个文件,其含义由文件格式决定。文件格式描述文件中有效的字节序列以及该序列的含义。它不是对文件格式级别重要的字节的一些解释 - 它是字节的顺序和排列。

如上所述,BMP文件格式提供了一种存储光栅图形的方法。它说前两个字节必须是01000010 01001101,接下来的四个字节必须给出文件的大小作为字节数的计数,依此类推,直到实际的像素数据。

二进制文件可以在其中包含编码。为了说明这一点,请考虑前面的示例。我说BMP文件中前两个后面的四个字节给出了文件的大小(以字节为单位)。这些字节是如何解释的? BMP文件格式声明这些字节将大小赋予无符号整数。这是这些字节的编码。

因此,当您在计算机上浏览目录中的BMP文件并将其打开时,您的系统如何知道如何打开它?它如何知道用于查看它的程序?文件扩展名比文本文件的编码强烈暗示二进制文件的格式。如果文件名末尾有.bmp,您的系统可能会将其视为BMP文件,只需在您拥有的任何图形程序中打开它。它也可以查看前几个字节并查看它们的建议。

摘要

理解文件中字节含义的第一个层次是该文件的格式。文本文件格式非常简单 - 从头开始​​,解释字符直到结束。如何解释字符取决于该文本文件的字符编码。但是,大多数格式都比较复杂,并且可能会将编码嵌套在其中。在某种程度上,你必须从字节和编码所在的位置开始提取抽象信息。但是,编码的任何内容也可以采用适用于它的格式。在获得所需信息之前,您需要一系列格式和编码。