C struct stat info不在循环中更新,给出了荒谬的修改日期

时间:2015-09-13 03:11:09

标签: c file directory stat

对于代码的一部分,我需要将给定目录中每个文件的名称和统计信息(用户ID,组ID,修改时间,权限等)保存到自定义结构的数组中。将数据保存到数组中是很好的,所以为了清楚起见,我将这些内容留了下来。我遇到的问题是使用预定义的struct stat:在测试中,它为目录中的每个文件打印出相同的确切修改日期,这是一个问题,日期是1969年,这是另一个问题(考虑到我清楚地记得去年某个时候创建​​和修改这些文件)。我不确定出了什么问题;一些帮助将不胜感激。

注意:这是我第一次用C编码,所以如果有任何明显的错误,请告诉我。我的教授在独立研究方面非常重要,并没有完全涵盖所有重要的事情。此外,我知道我需要检查错误 - 这些检查已经编写并将在以后实施。我只需要在担心所有错误检查之前修复此代码的晴天部分,所以请不要告诉我这是我的问题。我总是给它一个简单的'可读目录。打开或阅读应该没有问题。

  int main ()
  {
        DIR *myDIR;
        struct dirent *mydirent = malloc(sizeof(struct dirent));        //necessary?
        struct stat mystat;
        myDIR = opendir(pathname);
        int count = 0;
        while ((mydirent = readdir(myDIR)) != NULL)
             count++;
        rewinddir(myDIR);
        struct file_info **file_info_array = malloc(sizeof(struct file_info*)*(count+1));
        int i = 0;
        while ((mydirent = readdir(myDIR)) != NULL)
        {
             stat(mydirent->d_name, &mystat);
             printf("name: %s\n", mydirent->d_name);
             printf("mod_time: %s\n", ctime(&mystat.st_mtime));

             /*
             ... saving file info into file_info_array
             */

        }
        int is_closed = closedir(myDIR);

        /*
        ... freeing pointers
        */

        return 0; 
  }

1 个答案:

答案 0 :(得分:1)

将评论转换为答案。

您没有检查stat()是否成功;你不能推迟错误检查 - 它不是安全的。如果失败,则无法保证stat结构的内容是合理的。而且您还没有说明pathname是如何设置的。如果路径名不是.(或.的同义词),则stat()调用失败;您需要将readdir()返回的名称转换为相对于pathname的名称 - 例如:

char path[PATH_MAX];    /* <limits.h> - if it is defined at all */
snprintf(path, sizeof(path), "%s/%s", pathname, mydirent->d_name);
if (stat(path, &mystat) == 0)
{
    …go ahead with printing, etc…
}
  

哦,天哪,这就是原因!它需要是一条完整的道路吗?这是有道理的,但出于某种原因,当其他同学编码时,他们按照我原来的方式实现它,只是mydirent->d_name,并且没有问题。我想知道为什么?

不一定是完整的路径;只是一条可以找到的路径。如果您只是执行stat(mydirent->d_name, &mystat),那么您在当前目录中查找具有给定名称的文件 - 而不是从中读取名称的目录(除非该目录恰好是.)。也许同学们使用chdir(pathname)?或者他们只使用.(或.的同义词)作为路径名?

  

那么为什么它成功打印出所有名称,即使它们只存在于输入的目录而不是我当前的名称?我不想和你争辩;我真的很好奇stat()dirent的实际工作方式。

readdir()pathname指定的目录中读取名称(仅;没有路径信息)。所以它可以打印。一般情况下,stat()会失败,因此您需要打印垃圾以获取信息。

John Bollinger commented

  

另外,对于struct dirent,malloc()空间不是必需的,因为你声明了一个可以指向它的变量。您需要在可以安全地取消引用它之前为变量分配一个有效值,但是您可以通过指定readdir()的返回值来实现,假设readdir()成功。 -

正如John Bollinger所说,malloc()是不必要的,更糟糕​​的是,它是一个内存泄漏。