簡體   English   中英

如何在c中確定linux中的目錄或文件

[英]how to determine directory or file in linux in c

我只想打印文件名而不打印目錄名。 所以,我實現了這個功能

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);
  }
}

我檢查了目錄名稱是否以“/”字符結尾。 因此,我檢查了名稱末尾是否有“/”字符,不要打印該名稱,但是當我運行該函數時,所有這些都打印在選定目錄中?

你能指導我如何檢查目錄名稱的結尾嗎?

您正在尋找的是stat或其變體之一。 具體看struct statst_mode字段。 您感興趣的宏是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,您可以使用struct direntd_type字段(它不是POSIX 的一部分,而是Linux 的一部分)。

話雖如此,代碼如下。

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);
  }
}

它更干凈,不需要malloc

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.

根據需要嘗試使用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() 統計path指向的文件並填充buf。

  2. lstat() 與 stat() 相同,除了如果 path 是符號鏈接,則鏈接本身是 stat-ed,而不是它引用的文件。

  3. fstat() 與 stat() 相同,除了要統計的文件由文件描述符 fd 指定。

它們都返回一個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也可以幫助您,因為它包含文件的許多不同信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM