【问题标题】:stat() error 'No such file or directory' when file name is returned by readdir()当 readdir() 返回文件名时,stat() 错误“没有这样的文件或目录”
【发布时间】:2011-07-04 19:09:55
【问题描述】:

我无法识别 stat 引发的错误。以下程序读取目录中的所有文件并打印文件名:

DIR *dp;
struct dirent *dirp;
struct stat sb;

if((dp = opendir(argv[1]))==NULL)
{
    perror("can't open dir");
}
while((dirp = readdir(dp))!=NULL)
{
    if (stat(dirp->d_name, &sb) == -1) {
        perror("stat");
    }   
    printf("File name:               %s \n",dirp->d_name);
}

样本输出:

/home/eipe
stat error: No such file or directory
File name:               copyofsample 
File name:               a.out 
File name:               . 
stat error: No such file or directory
File name:               udpclient.c 
File name:               .. 
stat error: No such file or directory
File name:               client.c 
stat error: No such file or directory
File name:               ftpclient.c 

以下是内容:

ls -l /home/eipe/c

-rwxr-xr-x 1 eipe egroup 7751 2011-02-24 15:18 a.out
-rw-r--r-- 1 eipe egroup  798 2011-02-24 13:50 client.c
-rw-r--r-- 1 eipe egroup   15 2011-02-24 15:34 copyofsample
-rw-r--r-- 1 eipe egroup 1795 2011-02-24 15:33 ftpclient.c
-rw-r--r-- 1 eipe egroup  929 2011-02-24 13:34 udpclient.c

【问题讨论】:

标签: c unix stat


【解决方案1】:

dirp->d_name 是目录中文件的名称:例如"udpclient.c"。因此文件的全名是"/home/eipe/c/udpclient.c" - 但您当前的工作目录是/home/eipe,所以stat() 正在尝试访问不存在的"/home/eipe/udpclient.c"

您可以使用chdir() 将工作目录更改为argv[1],也可以在调用stat() 之前将argv[1] 添加到每个文件名。

【讨论】:

    【解决方案2】:

    请注意,POSIX 2008 引入了fstatat() 和相关函数(系统调用),所有这些函数都以熟悉的函数名称的at 后缀来区分。它还定义了dirfd() 来获取与目录流关联的文件描述符。

    *at() 函数采用一个(或在renameat() 的情况下为两个)引用目录的打开文件描述符。这意味着在支持fstatat() 的系统上,另一种编码方式是:

    const char *name = argv[i];
    
    DIR *dp = opendir(dirname);
    if (dp == NULL)
    {
        fprintf(stderr, "failed to open directory %s (%d: %s)\n",
                name, errno, strerror(errno));
        return -1;
    }
    
    int dfd = dirfd(dp);    /* Very, very unlikely to fail */
    
    struct dirent *dirp;
    while ((dirp = readdir(dp)) != NULL)
    {
        struct stat sb;
        if (fstatat(dfd, dirp->d_name, &sb, 0) == -1) {
            fprintf(stderr, "fstatat(\"%s/%s\") failed (%d: %s)\n",
                    name, dirp->d_name, errno, strerror(errno));
        }
        else
            printf("%-20s %s/%s\n", "File name:", name, dirp->d_name);
    }
    

    使用fstatat() 和相关函数允许您使用相对路径名而不使用chdir()(这很危险;如果不使用fchdir(),很难回到您开始的位置),或者连接名称,如主要接受的答案。出于可移植性考虑,仍然建议使用串联——但我能够使用下面的代码在 Mac OS X (10.10.1) 和 Linux (Ubuntu 14.04) 上进行测试。

    开发成完整的程序(test-fstatat.c):

    /* SO 0512-5919 */
    #define _XOPEN_SOURCE 700   /* POSIX 2008 plus ... */
    #include <dirent.h>
    #include <errno.h>
    #include <stdio.h>
    #include <string.h>
    #include <sys/stat.h>
    #include <unistd.h>
    
    int main(int argc, char **argv)
    {
    
        if (argc < 2)
        {
            fprintf(stderr, "Usage: %s directory [...]\n", argv[0]);
            return -1;
        }
    
        for (int i = 1; i < argc; i++)
        {
            const char *name = argv[i];
    
            DIR *dp = opendir(name);
            if (dp == NULL)
            {
                fprintf(stderr, "failed to open directory %s (%d: %s)\n",
                        name, errno, strerror(errno));
                return -1;
            }
    
            int dfd = dirfd(dp);    /* Very, very unlikely to fail */
    
            printf("%-20s %s\n", "Directory:", name);
    
            struct dirent *dirp;
            while ((dirp = readdir(dp)) != NULL)
            {
                struct stat sb;
                if (fstatat(dfd, dirp->d_name, &sb, 0) == -1) {
                    fprintf(stderr, "fstatat(\"%s/%s\") failed (%d: %s)\n",
                            name, dirp->d_name, errno, strerror(errno));
                }
                else
                    printf("%-20s %s/%s\n", "File name:", name, dirp->d_name);
            }
    
            closedir(dp);
        }
        return 0;
    }
    

    示例运行:

    $ test-fstatat ~/bin/JLSS-Dist/RCS ../../../src/sqltools/idsmon
    Directory:           /Users/jonathanleffler/bin/JLSS-Dist/RCS
    File name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/.
    File name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/..
    File name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/mkbod.sh,v
    File name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/jlssdist.jdc,v
    File name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/old.msd.sh,v
    File name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/chksumtool.pl,v
    File name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/msd2nmd.pl,v
    File name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/mknmd.sh,v
    File name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/publictimestamp.sh,v
    File name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/new.mknmd.sh,v
    File name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/PRODCODE,v
    File name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/prodverstamp.sh,v
    File name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/md5.create.pl,v
    File name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/jdcrelease.sh,v
    File name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/JLSS-Dist.mk,v
    File name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/PRODUCT,v
    File name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/msd.create.sh,v
    File name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/distribution.mk,v
    File name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/nmd.create.sh,v
    File name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/jlss.sh,v
    File name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/VERSION,v
    File name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/cvtjdc.sh,v
    File name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/redonmd.sh,v
    File name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/updmsd.sh,v
    File name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/setnmd.sh,v
    File name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/list2msd.pl,v
    File name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/chkmsdnmd.sh,v
    File name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/vercmp.pl,v
    File name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/MSD.sh,v
    File name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/setjdcversion.sh,v
    File name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/sortnmd.sh,v
    File name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/gennmd.sh,v
    File name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/md5.verify.pl,v
    File name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/setbomversion.sh,v
    File name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/chkbodlst.sh,v
    File name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/updnmd.sh,v
    File name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/domsd.sh,v
    File name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/md5.chksum.pl,v
    File name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/bomrelease.pl,v
    File name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/mkmsd.sh,v
    File name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/fixnmd.sh,v
    Directory:           ../../../src/sqltools/idsmon
    File name:           ../../../src/sqltools/idsmon/.
    File name:           ../../../src/sqltools/idsmon/..
    File name:           ../../../src/sqltools/idsmon/idstest.c
    File name:           ../../../src/sqltools/idsmon/idslen
    File name:           ../../../src/sqltools/idsmon/install-sh
    File name:           ../../../src/sqltools/idsmon/scatterinfo
    File name:           ../../../src/sqltools/idsmon/ltmain.sh
    File name:           ../../../src/sqltools/idsmon/idsmon.msd
    File name:           ../../../src/sqltools/idsmon/idsmon.o
    File name:           ../../../src/sqltools/idsmon/configure
    File name:           ../../../src/sqltools/idsmon/genscatter
    File name:           ../../../src/sqltools/idsmon/config
    File name:           ../../../src/sqltools/idsmon/idspacket
    File name:           ../../../src/sqltools/idsmon/genconnpacket
    File name:           ../../../src/sqltools/idsmon/Makefile
    File name:           ../../../src/sqltools/idsmon/config.h.in
    File name:           ../../../src/sqltools/idsmon/config.guess
    File name:           ../../../src/sqltools/idsmon/depcomp
    File name:           ../../../src/sqltools/idsmon/sqlihexdump.o
    File name:           ../../../src/sqltools/idsmon/missing
    File name:           ../../../src/sqltools/idsmon/install.mk
    File name:           ../../../src/sqltools/idsmon/sqlihexdump
    File name:           ../../../src/sqltools/idsmon/RCS
    File name:           ../../../src/sqltools/idsmon/Makefile.am
    File name:           ../../../src/sqltools/idsmon/test.istar.logs.tar.gz
    File name:           ../../../src/sqltools/idsmon/idstest.o
    File name:           ../../../src/sqltools/idsmon/esqlc.mk
    File name:           ../../../src/sqltools/idsmon/config.sub
    File name:           ../../../src/sqltools/idsmon/idspacket.o
    File name:           ../../../src/sqltools/idsmon/compile
    File name:           ../../../src/sqltools/idsmon/Old.Releases
    File name:           ../../../src/sqltools/idsmon/esqlc-nosfx.mk
    File name:           ../../../src/sqltools/idsmon/osiris_11
    File name:           ../../../src/sqltools/idsmon/config.h.in~
    File name:           ../../../src/sqltools/idsmon/idstest
    File name:           ../../../src/sqltools/idsmon/idsmon.c
    File name:           ../../../src/sqltools/idsmon/acr.decode
    File name:           ../../../src/sqltools/idsmon/sqlihexdump.dSYM
    File name:           ../../../src/sqltools/idsmon/toru.istar
    File name:           ../../../src/sqltools/idsmon/dumpdblflt
    File name:           ../../../src/sqltools/idsmon/sqlipacket.c
    File name:           ../../../src/sqltools/idsmon/toru
    File name:           ../../../src/sqltools/idsmon/data.info.tgz
    File name:           ../../../src/sqltools/idsmon/idsmon.nmd
    File name:           ../../../src/sqltools/idsmon/idsmon.jdc
    File name:           ../../../src/sqltools/idsmon/idsmon
    File name:           ../../../src/sqltools/idsmon/idsmon.black_19
    File name:           ../../../src/sqltools/idsmon/Makefile.in
    File name:           ../../../src/sqltools/idsmon/aclocal.m4
    File name:           ../../../src/sqltools/idsmon/sqlihexdump.c
    File name:           ../../../src/sqltools/idsmon/dumpdblflt.dSYM
    File name:           ../../../src/sqltools/idsmon/dumpdblflt.c
    $
    

    【讨论】:

      猜你喜欢
      • 2021-03-05
      • 2012-08-05
      • 1970-01-01
      • 1970-01-01
      • 2021-06-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多