stat函数:没有这样的文件或目录错误

时间:2012-08-08 08:05:01

标签: c++ c freebsd stat

当我的程序尝试stat()包含特定UTF-8字符的文件时,stat()函数会返回错误。例如,我可以使用vi打开文件/tmp/surgateDlpMgQure/Özkul Gazete,但将同一文件传递给stat()会产生错误。系统区域设置为:

  

LANG =的en_US.UTF-8

     

LC_CTYPE = “的en_US.UTF-8”

     

LC_COLLATE = C

     

LC_TIME = “的en_US.UTF-8”

     

LC_NUMERIC = “的en_US.UTF-8”

     

LC_MONETARY = “的en_US.UTF-8”

     

LC_MESSAGES = “的en_US.UTF-8”

     

LC_ALL =

我应该为stat()了解UTF-8字符做些什么吗?

以下是代码:

int main ()
{
    struct stat s;
    if (stat("/tmp/surgateDlpMgQure/Özkul Gazete", &s) == -1)
            perror("stat");


    switch (s.st_mode & S_IFMT) {
            case S_IFBLK:  printf("block device\n");            break;
            case S_IFCHR:  printf("character device\n");        break;
            case S_IFDIR:  printf("directory\n");               break;
            case S_IFIFO:  printf("FIFO/pipe\n");               break;
            case S_IFLNK:  printf("symlink\n");                 break;
            case S_IFREG:  printf("regular file\n");            break;
            case S_IFSOCK: printf("socket\n");                  break;
            default:       printf("unknown?\n");                break;
    }

 return 0;
}

3 个答案:

答案 0 :(得分:0)

问题可能是文件名的编码不是 与您在程序中内部使用的编码相同。钥匙 这里的问题是谁创建了文件(并给它这个名字),和 代码中的字符串来自哪里。大多数Unix都是不可知的 关于编码,只要几个特殊字符就好 '/',具有预期的编码。因此,独立于您的 当前语言环境,文件名可以是Latin-1,Latin-5(只是猜测, 但这个名字看起来像土耳其语)或UTF-8。在Unix中几乎没有任何关心, 但必须确保在程序中使用相同的编码 用于创建文件,或名称不匹配。 (在实践中, 我发现最简单的策略是限制字符中的字符 文件名到一个非常小的集合:ASCII字母数字字符,数字, '_',可能还有'-'。)

如果您不确定磁盘上文件名的实际编码, 您可以使用ls | od -t x1 -tc找出实际值 其中的字节。如果Ö为0xD6,则编码为Latin-1 或拉丁语-5(它可能不会有太大的区别),和 您必须确保传递的文件名为stat(或open,或 采用文件名的任何其他函数都在其中一个中编码 编码。相反,如果你有两个字节序列0xC3,0x96,那么 文件名是UTF-8。

如果您确实想支持ASCII子集之外的字符,那么 我强烈建议您确保所有文件名都已编码 在UTF-8中。假设您可以 - 编码将由 创建文件的程序,如果它不是你的程序(或如果 你从另一个系统接收文件),你可能无法 做任何事情。在最糟糕的情况下,您甚至可能必须这样做 使用opendirreaddir与某种匹配算法进行查找 实际文件名(无论编码如何),并使用它。

答案 1 :(得分:0)

我认为由于该文件名名称中的空格而存在问题...

你可以尝试更改没有空格的文件名

Özkul Gazete  -> Özkul_Gazete

在Linux上,我通常不会在文件名或目录名中使用空格

答案 2 :(得分:-1)

简单的方法来解决它:

使用该unicode字符的转义表示:

"/tmp/surgateDlpMgQure/\x00\xF6zkul Gazete"

我没有测试,但它应该工作。虽然这不是用C语言中的unicode字符串的方式。

很奇怪,你的代码可以在我的系统上运行,但不适用于我的系统:)