• Linux C如何判断文件类型?


    通过stat()读取指定文件状态, 然后通过宏测试struct stat的st_mode成员得到文件类型.
    stat函数有3个版本, 它们的区别是stat参数需要一个文件路径, fstat需要一个已打开文件描述符, lstat不跟随符号链接(当文件是符号链接时, 获得符号链接自身文件状态, 而不是获得其指向的文件状态)

    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>
    
    int stat(const char *pathname, struct stat *statbuf);
    int fstat(int fd, struct stat *statbuf);
    int lstat(const char *pathname, struct stat *statbuf);
    

    struct stat定义

    struct stat {
       dev_t     st_dev;         /* ID of device containing file */
       ino_t     st_ino;         /* Inode number */
       mode_t    st_mode;        /* File type and mode */
       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;     /* Block size for filesystem I/O */
       blkcnt_t  st_blocks;      /* Number of 512B blocks allocated */
    
       /* Since Linux 2.6, the kernel supports nanosecond
          precision for the following timestamp fields.
          For the details before Linux 2.6, see NOTES. */
    
       struct timespec st_atim;  /* Time of last access */
       struct timespec st_mtim;  /* Time of last modification */
       struct timespec st_ctim;  /* Time of last status change */
    
    #define st_atime st_atim.tv_sec      /* Backward compatibility */
    #define st_mtime st_mtim.tv_sec
    #define st_ctime st_ctim.tv_sec
    };
    

    可以通过宏确定文件类型

    文件类型
    S_ISREG() 普通文件
    S_ISDIR() 目录文件
    S_ISCHR() 字符特殊文件
    S_ISBLK() 块特殊文件
    S_ISFIFO() 管道或FIFO
    S_ISLNK() 符号链接
    S_ISSOCK() 套接字

    也可以通过宏确定IPC(进程间通信)对象类型

    文件类型
    S_TYPEISMQ() 消息队列
    S_TYPEISSEM() 信号量
    S_TYPEISSHM() 共享内存对象

    文件类型宏测试实质是按位与运算, 我们也可以手动按位与运算. 以S_ISDIR为例, 在unistd.h中, 其定义:

    #define S_ISDIR(mode) ((mode) & S_IFMT) == S_IFDIR)
    

    示例: 创建2个文件, 分别是普通文件类型和目录, 判断并打印出文件类型
    更详细的示例 参见man 2 stat

    #include <unistd.h>
    #include <sys/stat.h>
    #include <sys/types.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <fcntl.h>
    
    #define FILE_NUM  2
    
    void printFileType(char *path) {
        struct stat stat_buf;
        int ret = stat(path, &stat_buf);
        if (ret < 0) {
            perror("stat error");
            return;
        }
    
        if (S_ISREG(stat_buf.st_mode)) {
            printf("%s: general file
    ", path);
        }
        else if(S_ISDIR(stat_buf.st_mode)) {
            printf("%s: direcotry
    ", path);
        }
        else {
            printf("%s: other file type
    ", path);
        }
    }
    
    int main() {
        char *filepaths[FILE_NUM] = {
            "./file", "./dir"
        };
    
        int ret = -1;
        for (int i = 0; i < FILE_NUM; ++i){
            if (access(filepaths[i], O_RDONLY) < 0) {
                ret = creat(filepaths[i], 0664);
    
                if (ret < 0) {
                    perror("creat error");
                    exit(1);
                }
            }
        }
    
        for (int i = 0; i < FILE_NUM; ++i) {
            printFileType(filepaths[i]);
    
        }
        return 0;
    }
    

    运行结果

    $ touch file
    $ mkdir dir
    $ ./a.out 
    ./file: general file
    ./dir: direcotry
    
  • 相关阅读:
    对象数组输出学生信息
    对象数组实现添加和显示客户信息
    控制台输出模拟注册登录幸运抽奖
    对象数组和for循环遍历输出学生的信息
    控制台输出<迷你DVD管理>
    CF524B 题解
    优先队列的重载运算符
    [洛谷日报第19期]Codeforces游玩攻略(转)
    最短路(三种基础算法)
    P2032 扫描
  • 原文地址:https://www.cnblogs.com/fortunely/p/14771080.html
Copyright © 2020-2023  润新知