我是C的新手但尝试了一些系统调用。
我正在编写程序,遍历目录中的所有文件并打印当前文件名和大小。我可以让程序打印文件名,但是当我执行stat系统调用时它会出错。
以下是一些代码:
while (dptr = readdir(dirp)) {
if (stat(dptr->d_name, &buf) != 0) {
//Always does this and it does print the file name
printf("Error on when getting size of %s \n", dptr->d_name);
} else {
//Never gets here
printf("%u", buf.st_size);
}
}
我有这样描述的结构:
struct stat buf;
struct dirent *dptr;
DIR *dirp;
如果我改变:
if (stat(dptr->d_name, &buf) != 0)
到
if (stat(dptr->d_name, &buf) != [EACCES])
它仍然进入循环,这使我认为它无法读取文件名,但它在错误语句中打印它没有问题。
有人能指出我正确的方向吗?谢谢!
Аркадий
答案 0 :(得分:4)
首先,如果遇到错误,stat()返回-1,而不是实际的错误代码。错误代码将在errno中设置。打印错误的一种简单方法是使用perror()。
其次,dptr-> d_name仅提供文件的相对文件名,而不是完整文件名。要获取完整文件名,必须从相对文件名和目录名生成它。
以下是一个例子:
int cwdloop(void)
{
DIR * dirp;
struct stat buff;
struct dirent * dptr;
char filename[1024];
char dirname[1024];
if (!(getcwd(dirname, 1024)))
{
perror("getcwd");
return(1);
};
dirp = opendir(dirname);
if (!(dirp))
{
perror("opendir()");
return(1);
};
while ((dptr = readdir(dirp)))
{
snprintf(filename, 1024, "%s/%s", dirname, dptr->d_name);
if (stat(filename, &buff) != 0)
{
perror("stat()");
return(1);
} else {
printf("size: %u\n", (unsigned)buff.st_size);
};
};
closedir(dirp);
return(0);
}
答案 1 :(得分:3)
如果您知道确切的错误,这些事情会更容易处理。尝试
printf("error = %d: %s", errno, strerror(errno));
答案 2 :(得分:3)
这种代码的一个常见问题是仅使用文件名作为路径名。 dirent结构的d_name
条目不提供完整路径名,但提供了相对于目录的路径名。
要解决此问题,您可以
构建完整路径名,然后将其传递给stat
或
chdir
之前, stat
到目录。
答案 3 :(得分:0)
该问题的直接答案包含在其他答案中。我提供此为免费答案。在调试stat()
系统调用时,可能会发现以下函数有助于很好地格式化返回的状态缓冲区。
如何格式化,打印或记录stat()
系统调用:
static void logstat(struct stat *sp)
{
int mode = sp->st_mode;
if (sp->st_size > 1000000000)
printf(" File Size: %lluGB\n", sp->st_size / 1000000000);
else if(sp->st_size > 1000000)
printf(" File Size: %lluMB\n", sp->st_size / 1000000);
else
printf(" File Size: %llu bytes\n", sp->st_size);
printf(" Number of Links: %d\n", sp->st_nlink);
printf(" File inode: %d\n", sp->st_ino);
printf(" File type: ");
switch (mode & S_IFMT) {
case S_IFBLK:
printf("BLK\n");
break;
case S_IFCHR:
printf("CHR\n");
break;
case S_IFDIR:
printf("DIR\n");
break;
case S_IFIFO:
printf("FIFO\n");
break;
case S_IFLNK:
printf("LINK\n");
break;
case S_IFREG:
printf("REG\n");
break;
case S_IFSOCK:
printf("SOCK\n");
break;
}
printf(" File Permissions: ");
printf( (S_ISDIR(sp->st_mode) ? "d" : "-");
printf( (sp->st_mode & S_IRUSR) ? "r" : "-");
printf( (sp->st_mode & S_IWUSR) ? "w" : "-");
printf( (sp->st_mode & S_IXUSR) ? "x" : "-");
printf( (sp->st_mode & S_IRGRP) ? "r" : "-");
printf( (sp->st_mode & S_IWGRP) ? "w" : "-");
printf( (sp->st_mode & S_IXGRP) ? "x" : "-");
printf( (sp->st_mode & S_IROTH) ? "r" : "-");
printf( (sp->st_mode & S_IWOTH) ? "w" : "-");
printf( (sp->st_mode & S_IXOTH) ? "x" : "-");
printf("\n\n");
}