【问题标题】:Directory inside directory is seen as file目录内的目录被视为文件
【发布时间】:2020-11-19 08:51:41
【问题描述】:

我正在尝试打开一个目录并读取文件和文件夹,如果它是一个文件夹,则在末尾添加“/”。这是我当前的代码。

#include <dirent.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

int isDir(const char* target)
{
   struct stat statbuf;
   stat(target, &statbuf);
   return S_ISDIR(statbuf.st_mode);
}

int main(int argc, char * argv[])
{
    puts("");
  struct stat sfile;
    struct dirent *dp;
    char * dir;
    if(argc != 2) 
        dir = getenv("PWD"); //default
    else
        dir = argv[1];

    DIR *dirp = opendir(dir);
    dp = readdir(dirp);
    while ( dp != NULL ) 
    {
    stat(dp->d_name,&sfile);
    //opendir(dp->d_name);
    printf("Size : %ld      ",sfile.st_size);
        if (isDir(dp->d_name))
        {
            printf("%s/\n",dp->d_name);
        }
        else
        {
            printf("%s      \n",dp->d_name);
        }
        dp = readdir(dirp);
  }
  printf("\n");
    closedir(dirp);
}

这在我不传递任何参数时有效,即它正在读取当前工作目录中的文件和文件夹。当我将目录作为参数传递时,它无法将其中的其他文件夹检测为目录。奇怪的是,当我尝试使用 opendir() 打开时尝试使用 errno 时,所有内容都被检测为目录。

int isDir2(const char* target)
{
    opendir(target);
    if(errno == ENOTDIR)
    {
            puts("Not directory");
            return 0;
    }       
    else
    {
        puts("Directory"); //only this is getting printed
        return 1;
    }
}

在任何一种情况下,当两个 '.'和 '..' 被检测为目录,但其余部分为目录或文件,具体取决于我使用的是 opendir() 的 errno 还是 S_ISDIR。

【问题讨论】:

  • 在验证结果不成功之前检查errno 不是一个好主意。并非所有函数都会在成功时将 errno 设置为零。

标签: c file stat


【解决方案1】:

您的isDir 函数实际上并没有检查来自stat 的返回值来验证它是否成功。而且由于您的 statbuf 变量未初始化,因此它是未定义的行为。

更好:

int isDir(const char* target)
{
   struct stat statbuf = {0};
   int result = 0;
   if (stat(target, &statbuf) != -1)
   {
       result = S_ISDIR(statbuf.st_mode);
   }
   return result;
}

此外,您正在调用 opendir 而不分配它的返回值:

while ( dp != NULL ) 
    {
    stat(dp->d_name,&sfile);
        opendir(dp->d_name);  // WHERE'S THE RESULT?

关于调用opendirreaddir,您需要重新考虑在此while 循环中的逻辑,并且不要忘记调用closedir

【讨论】:

  • 我按照你说的修改了函数,但不影响输出。此外,opendir() 调用是我正在测试但忘记删除的东西。这两种方式都没有任何区别。
【解决方案2】:

所以问题在于工作目录。当我检查 isDir() 函数中的 stat 函数返回什么时,它返回 -1。它无法找到文件/文件夹,因为它的当前工作目录不是给定的文件夹,而是运行程序的 cwd。我所做的是将目录更改为给定的文件夹,它可以工作。

现在的代码:

#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>

int isDir(const char* target)
{
   struct stat statbuf = {0};
   int result = 0;
   int err = stat(target, &statbuf);
   if (err != -1)
   {
       result = S_ISDIR(statbuf.st_mode);
   }
   return result;
}

int main(int argc, char * argv[])
{
    puts("");
    struct stat sfile;
    struct dirent *dp;
    char * dir;
    if(argc != 2) 
        dir = getenv("PWD"); //default
    else
        dir = argv[1];
    DIR *dirp = opendir(dir);
    dp = readdir(dirp);
    chdir(dir);
    while ( dp != NULL ) 
    {
        stat(dp->d_name,&sfile);
        printf("Size : %ld      ",sfile.st_size);
        if (isDir(dp->d_name))
        {
            printf("%s/\n",dp->d_name);
        }
        else
        {   
            printf("%s      \n",dp->d_name);
        }
        dp = readdir(dirp);
  }
  printf("\n");
  closedir(dirp);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-24
    • 1970-01-01
    • 2011-11-02
    • 2010-10-10
    • 2016-04-05
    • 1970-01-01
    • 2014-10-21
    • 2013-03-27
    相关资源
    最近更新 更多