【问题标题】:C stat() ignoring filesC stat() 忽略文件
【发布时间】:2012-01-18 22:32:49
【问题描述】:

我遇到了 C 中的 stat 函数的问题。我的应用程序必须列出两个目录中的所有文件(第二个目录尚未实现)。当 dir1 设置为“.”时对于当前目录,它列出了所有文件。如果我将其更改为所需的目录,它只会列出一个文件。

#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>

main ()
{
    DIR *dir1;
    DIR *dir2;
    dir1 = opendir ("/home/tom/Documents/Uni/Dropbox/OS/C/1/");
    dir2 = opendir ("/home/tom/Documents/Uni/Dropbox/OS/C/2/");
    struct dirent *ent;
    struct stat fileStat;

    if (dir1 != NULL) 
    {
        /* while there are files to read in the directory */
        while ((ent = readdir (dir1)) != NULL) 
        {
        /*printf ("In 1\n"); <--debugging--> */
        if (stat(ent->d_name,&fileStat) == 0)
        {
            /* ignores . and .. and hidden files */
            /* printf ("In 2\n"); <--debugging--> */
            if(ent->d_name[0] != '.')
            {
                /* printf ("In 3\n"); <--debugging--> */
                printf ("\n");
                printf ("File: %s\n", ent->d_name);
                printf ("File size: %d\n", fileStat.st_size);
                printf ("-----------------------------------\n");
            }
        }
    }
    /* close the 1st directory */
    closedir (dir1);
    /* close the 2nd directory */
    closedir (dir2);
    }
    else 
    {
        /* prints an error if the  directory can not be opened */
        perror ("");
    } 
}

程序运行结果如下:

tom@x60deb:~/Documents/Uni/Dropbox/OS/C$ ./ffffuuuuuu 

File: ffffuuuuuu.c
File size: 1045
-----------------------------------

这是 ls 在它正在读取的目录中的结果:

tom@x60deb:~/Documents/Uni/Dropbox/OS/C/1$ ls -l
total 36
-rw-r--r-- 1 tom tom 356 Dec 12 23:36 cwTest2.c
-rw-r--r-- 1 tom tom 322 Dec 12 23:36 cwTest.c
-rw-r--r-- 1 tom tom 627 Dec 12 23:36 ffffuuuuuu.c
-rw-r--r-- 1 tom tom   6 Dec 12 23:32 file
-rw-r--r-- 1 tom tom   6 Dec 12 23:32 file2
-rw-r--r-- 1 tom tom   6 Dec 12 23:45 file2.file
-rw-r--r-- 1 tom tom  15 Dec 12 23:33 file3
-rw-r--r-- 1 tom tom  15 Dec 12 23:45 file3.file
-rw-r--r-- 1 tom tom   6 Dec 12 23:45 file.file

提前致谢, 汤姆。

【问题讨论】:

  • 你的当前目录是什么?这些条目与“/home/tom/Documents/Uni/Dropbox/OS/C/1/”相关(您应该给 stat() 完整的路径名)另外:条目比“.”多。和以“.”开头的“..”。
  • 输出stat的错误,你就知道是什么问题了。
  • @wildplasser 我在 /home/tom/Documents/Uni/Dropbox/OS 中运行它
  • @Beginner 我没有收到任何我知道的错误。它似乎只是跳过了一些文件。
  • 我认为 cmets 的重点是确定您跳过文件的原因。 readdir() 是否过早返回 NULL?在什么时候? stat() 是否失败,以至于您默默地跳过该代码块?在发生故障时进行报告将大大有助于解决您的问题。

标签: c stat


【解决方案1】:

您必须将stat() 的名称指定为绝对路径名或相对于当前目录的名称。

如果您的扫描仪正在更改目录,那么 (a) 你是一个比我更勇敢的人,并且 (b) 你可以使用短名称,但是 (c) 你必须担心如何回到原来的位置开始了。

如果你有 POSIX 2008,你也许可以使用系统调用的*at() 变体来简化生活;但我不确定有多少(如果有)系统支持这些调用。

【讨论】:

    【解决方案2】:
    #include <stdio.h>
    #include <string.h>
    #include <dirent.h>
    #include <sys/stat.h>
    #include <sys/types.h>
    
    int main (void)
    {
        char * dirname = "/home/tom/Documents/Uni/Dropbox/OS/C/1/" ;
        DIR *dir1;
        char path[11111];
        size_t len;
        struct dirent *ent;
        struct stat fileStat;
    
        dir1 = opendir (dirname);
        len = strlen ( dirname);
        memcpy(path, dirname, len+1);
    
        struct dirent *ent;
        struct stat fileStat;
    
        if (dir1 != NULL) 
        {
            /* while there are files to read in the directory */
            while ((ent = readdir (dir1)) != NULL) 
            {
            /*printf ("In 1\n"); <--debugging--> */
            strcpy(path+len, ent->d_name);
            if (stat( path,&fileStat) == 0)
            {
                /* ignores . and .. and hidden files */
                /* printf ("In 2\n"); <--debugging--> */
                if(ent->d_name[0] != '.')
                {
                    /* printf ("In 3\n"); <--debugging--> */
                    printf ("\n");
                    printf ("File: %s\n", ent->d_name);
                    printf ("File size: %d\n", fileStat.st_size);
                    printf ("-----------------------------------\n");
                }
            }
        }
        /* close the 1st directory */
        closedir (dir1);
        }
        else 
        {
            /* prints an error if the  directory can not be opened */
            perror ("");
        }
    return 0; 
    }
    

    更新,因为有些人看不懂,我会在这里添加我的原始评论:

    你的当前目录是什么?这些条目与“/home/tom/Documents/Uni/Dropbox/OS/C/1/”相关(您应该给 stat() 完整的路径名)另外:条目比“.”多。和以“.”开头的“..”。

    【讨论】:

    • 没有文字或任何内容说明您在此处为解决方案所做的工作。你做了什么?
    • 我在 OP 下的 cmets 中添加了它。差异是你的朋友。顺便说一句:我更新了。
    • 与我将代码剪切并粘贴到的本地应用程序中的差异,或者我不知道的本网站上的内容?顺便说一句,-1 不是我。
    • 任何花几分钟阅读的人都应该能够发现差异。否则他/她可以抓取内容,然后手动运行 diff。
    • 路径数组的大小应使用PATH_MAX(来自limits.h)而不是11111。
    猜你喜欢
    • 2021-07-19
    • 2018-05-12
    • 2021-12-19
    • 1970-01-01
    • 2018-08-31
    • 2019-05-30
    • 2012-06-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多