【问题标题】:Where is the character encoding of a text file stored in Linux?Linux 中存储的文本文件的字符编码在哪里?
【发布时间】:2016-03-27 20:08:25
【问题描述】:

我知道简短的回答应该是“无处”,但是在下面的测试 2 中有些东西并没有完全加起来。

测试 1. 在 Gedit 中,我创建了一个仅包含字符串“aàbï”的新文件,我选择“另存为”,并且有一个用于选择字符编码的选择器。所以我将它保存为“Unicode (UTF-8)”,然后我重复同样的操作,并将它保存到另一个文件中作为“ISO-8859-15”。第一个文件大小为 7 个字节(2 个 1 字节字符、2 个 2 字节字符和文件末尾的 LF,如十六进制转储所示)。第二个文件大小为 5 个字节(拉丁编码中的 4 个 1 字节字符加上一个 LF)。这表明编码未存储在文件中的任何位置。显然,当我在 Gedit 中打开文件并正确解码时,它必须通过分析内容来弄清楚如何解码。

测试2。我和上面一样,但是这次文件的内容只是“abcd”,也就是四个ascii字符。这两个保存的文件具有相同的大小(5 个字节)和相同的十六进制转储。看起来这两个文件是相同的,无法区分,因此,文件中似乎没有包含有关编码的信息。

但是,当我在 Gedit 中再次打开测试 2 的两个文件并转到另存为时,选择了保存文件的编码。 Gedit 不知何故可以分辨出一个文件是用 UTF-8 编码的,而另一个是用 ISO-8859-15 编码的,尽管两者都只包含导致相同字节序列的 ascii 字符并且它们看起来是相同的。怎么样?

文件系统中是否有某种元数据?还是只是 Gedit 有自己的缓存并记住用户对已在同一台计算机上打开(并保存)的给定文件的选择?

附:请注意,即使我提出了一个非编程测试用例,这个问题 也与编程有关,因为这是关于给定类型文件的编码方式,这会影响人们读取、解析、解码的方式,从程序中编码和编写它们。

【问题讨论】:

  • 可能是编辑器通过文件名缓存了编码,所以这将是易失性和专有信息,有时甚至会错过领先。纯文本文件的字符编码绝对存储在任何地方。实际上,您的第二个示例的两个文件实际上并没有不同的编码。它们仅包含两个 7 位字符的 4 个字符序列。此类字符串在大多数编码中都有效。
  • 为了方便未来读者遇到这个问题:我在野外看到了以字节顺序标记 u+FEFF 开头的 UTF-8 文件,以及使用它作为提示的软件内容是 Unicode 的一些变体。
  • 我在使用 xed 时也遇到过同样奇怪的问题 - 完全一样。我已经将这些文件与多个比较程序进行了比较,其中一些进行了二进制比较,并且所有报告都报告这两个文件是逐字节相同的。我已经更改了文件的名称并将它们复制到不同的目录中,但 xed 仍然拒绝使用 UTF-8 编码打开其中一个。 “字节顺序标记”不在这两个文件中。这个编码信息在某处被“记住”了!!!外面一定有人知道在哪里或如何。

标签: linux unicode encoding utf-8


【解决方案1】:

不是,至少默认情况下不是。实际上,这两个包含 abcd 的文件在文件系统中的存储方式没有区别,因为文本字符串 abcd 在两个语言环境的 ASCII 子集中编码相同。

Ext 文件系统不记录文件编码元数据。虽然可以通过使用扩展属性在 ext 文件系统上记录有限数量的数据(大约几千字节)以及文件,但 gedit 显然不使用它来存储字符编码,而是缓存特定用户的为特定文件选择编码。您可以通过以另一个用户身份登录(我在本实验中以 root 身份登录)并打开同一个文件来证明这一点——gedit 将使用默认系统区域设置读取它,而不是您在另一个登录时保存的自定义区域设置.

【讨论】:

  • 回复:“在第二种情况下,两个文件的编码实际上没有区别”:是的,这就是 OP 的重点。 (S)他故意创建了两个内容相同的文件。
  • @ruakh 为清楚起见而编辑并更直接地回答问题
【解决方案2】:

文件的编码不存储为文件的属性。相反,程序必须检查文件以查看哪种编码最合适。 Test1 很有趣,因为文件不同:

  • 从假设文件以 UTF-8 编码开始,gedit 将尝试将其解码为 UTF-8
  • ISO-8859-15 文件包含无效的 UTF-8 编码字节,因此gedit 会将其作为 ISO-8859-x 变体之一处理
  • ISO-8859-15 与其他标准(例如 ISO-8859-1)的不同之处在于它对相同数据的解释——这不是样本的一部分。
  • 缺少更多信息,无论gedit 告诉您较短的信息都将反映您的区域设置和gedit 配置,但基本上只是猜测。

使用 Test2,两个文件都使用 ASCII 编码(UTF-8 和 ISO-8859-15 的子集),因此没有其他信息:gedit 将再次依赖于您的语言环境以及是否要将文件用作 UTF-8 的配置。

进一步阅读:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-06
    • 1970-01-01
    • 2017-12-05
    • 2010-09-19
    相关资源
    最近更新 更多