调用fopen或open时使用的编码是什么?

15
当我们在Linux中调用系统调用,比如`open`,或者调用stdio库函数,比如`fopen`时,需要提供一个`const char * filename`参数。我的问题是这里使用的编码是什么?是UTF-8还是ASCII或ISO8859-X?这取决于系统或环境设置吗?
我知道在MS Windows中有一个名为`_wopen`的函数可以接受UTF-16编码。

相关:http://serverfault.com/questions/87055/change-filesystem-encoding-to-utf-8-in-ubuntu - Roger Pate
6个回答

9

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


5
Linux中的文件系统调用是与编码无关的,也就是说它们不需要知道特定的编码方式。对于它们来说,由filename参数指向的字节串会原封不动地传递给文件系统。文件系统要求文件名使用正确的编码(通常是UTF-8,正如Matthew Talbert所提到的那样)。
这意味着你通常不需要做任何事情(文件名被视为不透明的字节串),但这实际上取决于你从哪里接收到文件名以及你是否需要以任何方式操作文件名。

1
文件系统期望文件名采用正确的编码。通常的Linux文件系统(如ext系列)不需要任何编码,它们只需要一串字节。在Linux下,NTFS驱动程序确实与驱动程序和编码进行交互,但这是一个例外情况。 - n. m.

4

这取决于系统语言环境。查看“locale”命令的输出。如果变量以UTF-8结尾,则您的语言环境为UTF-8。大多数现代Linux系统都将使用UTF-8。尽管安德鲁正确地指出了它实际上只是一个字节字符串,但如果您不匹配系统语言环境,则某些程序可能无法正常工作,并且将无法获得正确的用户输入等。最好坚持使用UTF-8。


1
请注意,文件名可能采用的编码方式与系统默认编码不同,例如,如果您解压缩了一个由其他人使用不同编码打包的存档文件(tarball、ZIP等)。 - alvherre
1
确实,这是非常正确的。难道我们不希望每个人都使用UTF-8吗? - Matthew Talbert
不,它不依赖于“系统区域设置”。不存在所谓的系统区域设置。只有用户区域设置。openfopen的结果也不取决于用户区域设置。 - n. m.

1
文件名是一个字节字符串;无论使用哪种关于文件名编码的规定或约定,您必须传递给 fopen 和所有涉及文件名/路径名的函数的确切字节字符串就是该文件的名称。例如,如果您有一个以 UTF-8 编码为 NFC 的文件名为 ö.txt 的文件,并且您的区域设置(locale)为以 UTF-8 编码并使用 NFC,则可以将其写作 ö.txt 并将其传递给 fopen。但是,如果您的区域设置基于 Latin-1,则不能传递 Latin-1 形式的 ö.txt"\xf6.txt")到 fopen 并期望它成功;那是一个不同的字节字符串,因此是一个不同的文件名。您需要传递相同的字节字符串作为实际名称: "\xc3\xb6.txt"(如果将其解释为 Latin-1,则为 "ö.txt")。
这种情况与您熟悉的Windows非常不同,其中文件名是一系列解释为UTF-16的16位单元(尽管我认为它们不需要实际上是有效的UTF-16),传递给“fopen”等函数的文件名根据当前区域设置解释为Unicode字符,然后使用这些字符基于其UTF-16名称来打开/访问文件。

0

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


-1

我对这个话题进行了进一步的调查,并得出结论:unixoid文件系统处理文件名编码的方式有两种不同的方式。

  1. 文件名使用“系统语言环境”进行编码,通常情况下可以使用当前环境语言环境反映的 locale 命令(但是可能在全局配置文件中预设)。

  2. 文件名以UTF-8编码,独立于任何语言环境设置。

GTK+通过假定UTF-8并允许用当前语言环境编码或用户提供的编码覆盖它来解决此问题。

Qt则通过假定语言环境编码(并且系统语言环境反映在当前语言环境中)并允许使用用户提供的转换函数来解决此问题。

因此,重要的是:默认情况下使用UTF-8或LC_ALL或LANG告诉您的内容,至少为另一种替代方案提供覆盖设置。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接