2011-12-15 81 views
3

我是C新手,但尝试了一些系统调用。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]) 

它仍然进入循环,这让我认为它不能读取文件名,但它将错误语句打印出来没有问题。

有人能指出我正确的方向吗?谢谢!

Аркадий

+2

是您所提供的_full_路径的文件和文件夹的名称? – 2011-12-15 18:45:23

+2

`stat`永远不会返回`EACCES`。它将返回-1,然后将`errno`设置为`EACCES`。 – 2011-12-15 18:51:50

+0

当它在当前目录中时它工作吗? (根据@ codaddict的回答) – 2011-12-15 19:00:05

回答

3

首先,如果遇到错误,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); 
} 
3

这些东西是一个更容易对付,如果你知道确切的错误。尝试

printf("error = %d: %s", errno, strerror(errno)); 
+1

或者只是使用`perror()`。 – kennytm 2011-12-15 18:34:50

3

这种代码的一个常见问题是只使用文件名作为路径名。 dirent结构的d_name条目不提供完整的路径名,但提供了与您的目录相关的路径名。

要解决这一点,你可以

  1. 构建完整路径名,然后调用stat之前将它传递给stat

  2. chdir到目录中。