【问题标题】:What encoding used when invoke fopen or open?调用 fopen 或 open 时使用什么编码?
【发布时间】:2011-01-01 14:40:15
【问题描述】:

当我们在 linux 中调用像“open”这样的系统调用或像“fopen”这样的 stdio 函数时,我们必须提供一个“const char * filename”。我的问题是这里使用的编码是什么?它是 utf-8 还是 ascii 或 iso8859-x?是否取决于系统或环境设置?

我知道在 MS Windows 中有一个接受 utf-16 的 _wopen

【问题讨论】:

标签: c linux fopen system-calls


【解决方案1】:

文件名字节串;无论您使用的语言环境或任何其他关于如何编码文件名的约定,您必须传递给fopen 和所有采用文件名/路径名的函数的字符串都是文件命名方式的确切字节字符串。例如,如果您在 NFC 中以 UTF-8 格式有一个名为 ö.txt 的文件,并且您的语言环境是 UTF-8 编码并使用 NFC,您可以将名称写为 ö.txt 并将其传递给 fopen。但是,如果您的语言环境是基于 Latin-1 的,则您不能将 ö.txt ("\xf6.txt") 的 Latin-1 形式传递给 fopen 并期望它成功;那是一个不同的字节字符串,因此是一个不同的文件名。您需要传递"\xc3\xb6.txt""ö.txt",如果您将其解释为 Latin-1),与实际名称相同的字节字符串。

这种情况与您似乎熟悉的 Windows 非常不同,其中文件名 is 是解释为 UTF-16 的 16 位单元序列(尽管 AFAIK 他们实际上不需要是有效的 UTF-16)和传递给 fopen 等的文件名根据当前语言环境解释为 Unicode 字符,然后根据其 UTF-16 名称打开/访问文件.

【讨论】:

    【解决方案2】:

    如上所述,这将是一个字节串,其解释将对底层系统开放。更具体地说,想象一下 C 函数;一个在用户空间,一个在内核空间,以char *为参数。用户空间中的编码将取决于用户程序的执行字符集(例如,由 gcc 中的-fexec-charset=charset 指定)。内核函数预期的编码取决于内核编译期间使用的执行字符集(不确定从何处获取该信息)。

    【讨论】:

      【解决方案3】:

      我对这个主题做了一些进一步的调查,并得出结论,unixoid 文件系统可以通过两种不同的方式处理文件名编码。

      1. 文件名在“系统语言环境”中编码,通常与locale 命令反映的当前环境语言环境相同,但不必与当前环境语言环境相同(但在全局配置中有一些预设)文件)。

      2. 文件名以 UTF-8 编码,独立于任何区域设置。

      GTK+ 通过假设 UTF-8 并允许通过当前区域设置编码或用户提供的编码覆盖它来解决这个问题。

      Qt 通过假设语言环境编码(并且系统语言环境反映在当前语言环境中)并允许用用户提供的转换函数覆盖它来解决它。

      所以底线是:使用 UTF-8 或 LC_ALL 或 LANG 默认告诉您的内容,并至少为其他替代方案提供覆盖设置。

      【讨论】:

        【解决方案4】:

        Linux 上的文件系统调用与编码无关,即它们不需要(不需要)知道特定的编码。就他们而言,文件名参数指向的字节串按原样传递给文件系统。文件系统要求文件名采用正确的编码(通常是 UTF-8,如 Matthew Talbert 所述)。

        这意味着您通常不需要做任何事情(文件名被视为不透明的字节字符串),但这实际上取决于您从哪里接收文件名,以及您是否需要以任何方式操作文件名。

        【讨论】:

        • "文件系统期望文件名采用正确的编码" 通常的 Linux 文件系统(如 ext 系列)不期望任何编码。他们期望一串字节。 Linux 下的 NTFS 驱动程序确实与驱动程序和编码交互,但它们是一个例外。
        【解决方案5】:

        这取决于系统区域设置。查看“locale”命令的输出。如果变量以 UTF-8 结尾,那么您的语言环境是 UTF-8。大多数现代 linux 将使用 UTF-8。虽然 Andrew 是正确的,从技术上讲它只是一个字节字符串,但如果您不匹配系统区域设置,某些程序可能无法正常运行,并且无法获得正确的用户输入等。最好坚持使用 UTF-8。

        【讨论】:

        • 请注意,可能有文件的名称以系统默认编码以外的其他编码进行编码,例如,如果您解压缩由其他人打包的存档(tarball、ZIP 等)编码比你的。
        • 确实如此。我们不希望每个人都使用 UTF-8 吗?
        • 不,它不依赖于“系统语言环境”。没有系统语言环境之类的东西。只有用户语言环境。 openfopen 的结果也不取决于用户区域设置。
        【解决方案6】:

        它是一个字节串,解释取决于特定的文件系统。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-06-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-10-07
          • 2014-04-07
          • 1970-01-01
          相关资源
          最近更新 更多