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

时间:2010-01-05 11:09:29

标签: c linux fopen system-calls

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

我知道在MS Windows中有_wopen接受utf-16。

6 个答案:

答案 0 :(得分:8)

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

答案 1 :(得分:4)

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

答案 2 :(得分:4)

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

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

答案 3 :(得分:0)

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

答案 4 :(得分:0)

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

这种情况与您似乎熟悉的Windows有很大不同,文件名是由16位单元组成的序列,这些序列被解释为UTF-16(尽管AFAIK实际上并不需要是有效的UTF-16),并且传递给"ö.txt"等的文件名会根据当前语言环境解释为Unicode字符,然后用于根据文件的UTF- 16个名字。

答案 5 :(得分:-1)

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

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

  2. 文件名以UTF-8编码,与任何区域设置无关。

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

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

    所以底线是:默认情况下使用UTF-8或LC_ALL或LANG告诉你的内容,并至少为其他选项提供覆盖设置。