[英]stat() error 'No such file or directory' when file name is returned by readdir()
我無法識別 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
dirp->d_name
是目錄中文件的名稱:例如, "udpclient.c"
。 因此文件的全名是"/home/eipe/c/udpclient.c"
但你當前的工作目錄是/home/eipe
,所以stat()
試圖訪問"/home/eipe/udpclient.c"
,它不存在。
您可以使用chdir()
將您的工作目錄更改為argv[1]
,或者您可以在調用stat()
之前將argv[1]
到每個文件名。
請注意,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
$
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.