检查目录. readdir返回的条目是目录,链接或文件. dent-> d_type没有显示类型 [英] Checking if a dir. entry returned by readdir is a directory, link or file. dent->d_type isn't showing the type

查看:310
本文介绍了检查目录. readdir返回的条目是目录,链接或文件. dent-> d_type没有显示类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作一个程序,该程序在Linux shell中运行,并接受一个参数(目录),并显示目录中的所有文件及其类型.

I am making a program which is run in a Linux shell, and accepts an argument (a directory), and displays all the files in the directory, along with their type.

输出应如下所示:

 << ./Program testDirectory

 Dir directory1
 lnk linkprogram.c
 reg file.txt

如果不做任何参数,它将使用当前目录.这是我的代码:

If no argument is made, it uses the current directory. Here is my code:

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

int main(int argc, char *argv[])
{
  struct stat info;
  DIR *dirp;
  struct dirent* dent;

  //If no args
  if (argc == 1)
  {

    argv[1] = ".";
    dirp = opendir(argv[1]); // specify directory here: "." is the "current directory"
    do
    {
      dent = readdir(dirp);
      if (dent)
      {
        printf("%c ", dent->d_type);
        printf("%s \n", dent->d_name);

        /* if (!stat(dent->d_name, &info))
         {
         //printf("%u bytes\n", (unsigned int)info.st_size);

         }*/
      }
    } while (dent);
    closedir(dirp);

  }

  //If specified directory 
  if (argc > 1)
  {
    dirp = opendir(argv[1]); // specify directory here: "." is the "current directory"
    do
    {
      dent = readdir(dirp);
      if (dent)
      {
        printf("%c ", dent->d_type);
        printf("%s \n", dent->d_name);
        /*  if (!stat(dent->d_name, &info))
         {
         printf("%u bytes\n", (unsigned int)info.st_size);
         }*/
      }
    } while (dent);
    closedir(dirp);

  }
  return 0;
}

由于某些原因,dent->d_type没有显示文件类型.我不太确定该怎么办,有什么建议吗?

For some reason dent->d_type is not displaying the type of file. I'm not really sure what to do, any suggestions?

推荐答案

d_type是一种速度优化,可在受支持的情况下保存在lstat(2)调用中.

d_type is a speed optimization to save on lstat(2) calls, when it's supported.

readdir(3)手册页指出,并非所有文件系统在d_type字段中返回真实信息(通常是因为需要额外的磁盘搜索来读取inode,如果不使用mkfs.xfs -n ftype=1,则是XFS的情况(由-m crc=1表示,这还不是默认情况下,总是设置为DT_UNKNOWN的文件系统在现实生活中很常见,并不是您可以忽略的东西.XFS并不是唯一的例子.

As the readdir(3) man page points out, not all filesystems return real info in the d_type field (typically because it would take an extra disk seek to read the inode, as is the case for XFS if you didn't use mkfs.xfs -n ftype=1 (implied by -m crc=1 which is not yet the default). Filesystems that always set DT_UNKNOWN are common in real life, and not something that you can ignore. XFS is not the only example.

您始终需要使用 lstat(2)的代码如果是d_type==DT_UNKNOWN,则仅凭文件名不足以决定它没有意思. (对于某些调用程序,例如find -name或扩展的glob这样的*.c,就是这种情况,这就是为什么readdir不需要额外读取磁盘就不会产生填充它的开销的原因.)

You always need code that will fall back to using lstat(2) if d_type==DT_UNKNOWN, if the filename alone isn't enough to decide it's uninteresting. (This is the case for some callers, like find -name or expanding globs like *.c, which is why readdir doesn't incur the overhead of filling it in if it would take an extra disk read.)

Linux getdents(2) 手册页上有一个示例程序,它可以完成您的工作重新尝试做,包括一个链接的三元运算符块,将d_type字段解码为文本字符串. (正如其他答案所指出的那样,您的错误是将其作为字符打印出来,而不是与DT_REGDT_DIR等进行比较).

The Linux getdents(2) man page has an example program that does what you're trying to do, including a chained-ternary-operator block to decode the d_type field into text strings. (As the other answers point out, your mistake is printing it out as an character, rather than comparing it against DT_REG, DT_DIR, etc.)

无论如何,其他答案大多涵盖了所有内容,但是错过了需要后备的关键细节,因为d_type == DT_UNKNOWN(在Linux上为0.d_type是填充字节,直到Linux 2.6.4).

Anyway, the other answers mostly covered things, but missed the critical detail that you NEED a fallback for the case when d_type == DT_UNKNOWN (0 on Linux. d_type is stored in what used to be a padding byte, until Linux 2.6.4).

要便于移植,您的代码需要检查struct dirent甚至是否有d_type字段(如果使用的话),或者您的代码甚至不编译在GNU和BSD系统之外. (请参见readdir(3))

To be portable, your code needs to check that struct dirent even HAS a d_type field, if you use it, or your code won't even compile outside of GNU and BSD systems. (see readdir(3))

我写了 使用readdir查找目录的示例 ,并使用了d_type当d_type在编译时不可用,为DT_UNKNOWN时以及对于符号链接时,回退到stat.

I wrote an example for finding directories with readdir, using d_type with a fallback to stat when d_type isn't available at compile time, when it's DT_UNKNOWN, and for symlinks.

这篇关于检查目录. readdir返回的条目是目录,链接或文件. dent-&gt; d_type没有显示类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆