如何在c中确定linux中的目录或文件

时间:2015-06-16 20:03:57

标签: c linux

我想只打印文件名而不打印目录名称。所以,我实现了这个功能

void list_file(char* directory){
  DIR *d;
  struct dirent *dir;
  d = opendir(directory);
  if (d)
  {
    while ((dir = readdir(d)) != NULL)
    {
        printf("%c", dir->d_name[(int)strlen(dir->d_name)]);
        if(dir->d_name[(int)strlen(dir->d_name)-2] != '/')
            printf("%s\n", dir->d_name);
    }

    closedir(d);
  }
}

我检查了目录名称以' /'结尾字符。所以,我查了一下是否有' /'名称末尾的字符,不要打印该名称,但是当我运行该功能时,所有这些字符都打印在选定的目录中?

您能告诉我如何查看目录名称的结尾?

3 个答案:

答案 0 :(得分:8)

您正在寻找的是stat或其变体之一。具体来看st_mode struct stat字段。您感兴趣的宏是S_ISDIR(x)

在下面找到展示您想要的修改后的代码:

void list_file(char* directory) {
  DIR *d;
  struct dirent *dir;
  int dir_len = strlen(directory);
  char* path = malloc(dir_len + NAME_MAX + 2); // +2, 1 for '/' and 1 for '\0'
  if(path == NULL) {
    fprintf(stderr, "malloc failed\n");
    return;
  }
  strcpy(path, directory);
  if(path[dir_len-1] != '/') {
    path[dir_len] = '/';
    dir_len++;
  }
  d = opendir(directory);
  if (d) {
    while ((dir = readdir(d)) != NULL)
    {
      struct stat buf;
      strcpy(&path[dir_len], dir->d_name);
      if(stat(path, &buf) < 0) {
        fprintf(stderr, "error\n");
      }
      else {if(!S_ISDIR(buf.st_mode)) {
          printf("%s\n", dir->d_name);
        }
      }
    }

    closedir(d);
  }
  free(path);
}

我删除了你的第一个打印件,因为它正在打印字符串的空终止字符。

更新

正如我们处理Linux时所述,您可以使用d_type中的struct dirent字段(void list_file(char* directory){ DIR *d; struct dirent *dir; d = opendir(directory); if (d) { while ((dir = readdir(d)) != NULL) { struct stat buf; if(dir->d_type == DT_DIR) { printf("%s\n", dir->d_name); } } closedir(d); } } 不属于POSIX,但属于Linux })。

据说代码如下。

malloc

它更清洁,不需要onclick

答案 1 :(得分:3)

Linux上的

man readdir

On Linux, the dirent structure is defined as follows:

       struct dirent {
           ino_t          d_ino;       /* inode number */
           off_t          d_off;       /* not an offset; see NOTES */
           unsigned short d_reclen;    /* length of this record */
           unsigned char  d_type;      /* type of file; not supported
                                          by all filesystem types */
           char           d_name[256]; /* filename */
       };
[...]
Other than Linux, the d_type field is available mainly only on BSD sys‐
tems.   This  field  makes  it possible to avoid the expense of calling
lstat(2) if further actions depend on the type of  the  file.   If  the
_BSD_SOURCE  feature test macro is defined, then glibc defines the fol‐
lowing macro constants for the value returned in d_type:

   DT_BLK      This is a block device.

   DT_CHR      This is a character device.

   DT_DIR      This is a directory.

   DT_FIFO     This is a named pipe (FIFO).

   DT_LNK      This is a symbolic link.

   DT_REG      This is a regular file.

   DT_SOCK     This is a UNIX domain socket.

   DT_UNKNOWN  The file type is unknown.

答案 2 :(得分:3)

根据需要尝试使用stat, fstat, lstat之一。这用于获取文件状态。

用法:

int stat(const char *path, struct stat *buf);
int fstat(int fd, struct stat *buf);
int lstat(const char *path, struct stat *buf);
  1. stat()统计路径指向的文件并填写buf。

  2. lstat()与stat()相同,只是如果path是符号链接,则链接本身是stated ed,而不是它引用的文件。

  3. fstat()与stat()相同,不同之处在于要通过文件描述符fd指定要统计的文件。

  4. 所有这些结构都返回stat结构,其中包含以下字段:

    struct stat {
                   dev_t     st_dev;     /* ID of device containing file */
                   ino_t     st_ino;     /* inode number */
                   mode_t    st_mode;    /* protection */
                   nlink_t   st_nlink;   /* number of hard links */
                   uid_t     st_uid;     /* user ID of owner */
                   gid_t     st_gid;     /* group ID of owner */
                   dev_t     st_rdev;    /* device ID (if special file) */
                   off_t     st_size;    /* total size, in bytes */
                   blksize_t st_blksize; /* blocksize for filesystem I/O */
                   blkcnt_t  st_blocks;  /* number of 512B blocks allocated */
                   time_t    st_atime;   /* time of last access */
                   time_t    st_mtime;   /* time of last modification */
                   time_t    st_ctime;   /* time of last status change */
               };
    

    从这个尝试:

    buf.st_mode & S_IFMT                #assuming you have defined struct stat buf;
    

    将值与S_IFDIR进行比较,以检查它是否是目录。

    有关详情,请参阅:man 2 stat

    使用struct stat也可以为您提供帮助,因为它包含许多不同的文件信息。