zoukankan      html  css  js  c++  java
  • 文件I/O实践(2) --文件stat

    功能:获取文件元数据

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

    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 */
    };
    //示例   - err_exit函数如前
    // 其实可以通过Linux 系统调用major, minor来替换(如下)
    #define MAJOR(a) (int)((unsigned short)a >> 8)  //主设备号: 获取高8位
    #define MINOR(a) (int)((unsigned short)a & 0xFF)//次设备号: 获取低8位
    bool fileType(const struct stat &fileStat);
    void filePerm(const struct stat &fileStat, char *perm);
    
    int main(int argc, char *argv[])
    {
        if (argc != 2)
        {
            cerr << "Usage: " << argv[0] << " <file-name>" << endl;
            exit(EXIT_FAILURE);
        }
    
        struct stat fileStat;
        if (lstat(argv[1], &fileStat) == -1)
            err_exit("stat error");
    
        cout << "file-name: " << argv[1] << endl;
        cout << "st_ino = " << fileStat.st_ino << endl;
        cout << "device major: " << major(fileStat.st_dev)
             << ", minor: " << minor(fileStat.st_dev) << endl;
        if (fileType(fileStat))
        {
            cout << "----------------------------" << endl;
            cout << "major: " << MAJOR(fileStat.st_dev)
                 << ", minor: " << MINOR(fileStat.st_rdev) << endl;
    //        cout << "major: " << major(fileStat.st_dev)
    //             << ", minor: " << minor(fileStat.st_rdev) << endl;
        }
        //获取文件的权限: 但要注意需要&上07777
        fprintf(stdout, "file permission: %o", fileStat.st_mode&07777);
        char perm[11];
        filePerm(fileStat, perm);
        cout << ", msg: " << perm << endl;
    
        cout << "st_nlink = " << fileStat.st_nlink << endl;
        cout << "st_uid = " << fileStat.st_uid << endl;
        cout << "st_gid = " << fileStat.st_gid << endl;
        cout << "st_size = " << fileStat.st_size << endl;
        cout << "st_blksize = " << fileStat.st_blksize << endl;
        cout << "st_blocks = " << fileStat.st_blocks << endl;
        cout << "st_atime = " << fileStat.st_atime << endl;
        cout << "st_ctime = " << fileStat.st_ctime << endl;
        cout << "st_mtime = " << fileStat.st_mtime << endl;
    }
    
    bool fileType(const struct stat &fileStat)
    {
        cout << "file-type: ";
        switch(fileStat.st_mode & S_IFMT)
        {
        case S_IFSOCK:
            cout << "socket";
            break;
        case S_IFLNK:
            cout << "symbolic link";
            break;
        case S_IFREG:
            cout << "regular file";
            break;
        case S_IFBLK:
            cout << "block device" << endl;
            return true;
            break;
        case S_IFDIR:
            cout << "directory";
            break;
        case S_IFCHR:
            cout << "character device" << endl;
            return true;
            break;
        case S_IFIFO:
            cout << "FIFO" << endl;
            break;
        default:
            cout << "unknown?";
            break;
        }
        cout << endl;
        return false;
    }
    
    void filePerm(const struct stat &fileStat, char *perm)
    {
        strcpy(perm, "----------");
        switch(fileStat.st_mode & S_IFMT)
        {
        case S_IFSOCK:
            perm[0] = 's';
            break;
        case S_IFLNK:
            perm[0] = 'l';
            break;
        case S_IFREG:
            perm[0] = '-';
            break;
        case S_IFBLK:
            perm[0] = 'b';
            break;
        case S_IFDIR:
            perm[0] = 'd';
            break;
        case S_IFCHR:
            perm[0] = 'c';
            break;
        case S_IFIFO:
            perm[0] = 'p';
            break;
        default:
            perm[0] = '?';
            break;
        }
    
        if (fileStat.st_mode & S_IRUSR)
            perm[1] = 'r';
        if (fileStat.st_mode & S_IWUSR)
            perm[2] = 'w';
        if (fileStat.st_mode & S_IXUSR)
            perm[3] = 'x';
        if (fileStat.st_mode & S_IRGRP)
            perm[4] = 'r';
        if (fileStat.st_mode & S_IWGRP)
            perm[5] = 'w';
        if (fileStat.st_mode & S_IXGRP)
            perm[6] = 'x';
        if (fileStat.st_mode & S_IROTH)
            perm[7] = 'r';
        if (fileStat.st_mode & S_IWOTH)
            perm[8] = 'w';
        if (fileStat.st_mode & S_IXOTH)
            perm[9] = 'x';
    }


    [拓展]

    1.getpwuid 

    struct passwd *getpwuid(uid_t uid);
    //passwd结构体
    struct passwd
    {
        char   *pw_name;       /* username */
        char   *pw_passwd;     /* user password */
        uid_t   pw_uid;        /* user ID */
        gid_t   pw_gid;        /* group ID */
        char   *pw_gecos;      /* user information */
        char   *pw_dir;        /* home directory */
        char   *pw_shell;      /* shell program */
    };

    2.getgrgid

    struct group *getgrgid(gid_t gid);
    //group结构体
    struct group
    {
        char   *gr_name;       /* group name */
        char   *gr_passwd;     /* group password */
        gid_t   gr_gid;        /* group ID */
        char  **gr_mem;        /* group members */
    };

    3. readlink

    ssize_t readlink(const char *path, char *buf, size_t bufsiz);

    4. localtime

    struct tm *localtime(const time_t *timep);
    //tm结构体
    struct tm
    {
        int tm_sec;         /* seconds */
        int tm_min;         /* minutes */
        int tm_hour;        /* hours */
        int tm_mday;        /* day of the month */
        int tm_mon;         /* month */
        int tm_year;        /* year */
        int tm_wday;        /* day of the week */
        int tm_yday;        /* day in the year */
        int tm_isdst;       /* daylight saving time */
    };

    //示例: 实现简单的ls -l功能
    #include <iostream>
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <string.h>
    
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <grp.h>
    #include <pwd.h>
    #include <time.h>
    
    using namespace std;
    
    inline void err_exit(std::string message);
    bool isDevice(const struct stat &fileStat);
    bool isLink(const struct stat &fileStat);
    void filePerm(const struct stat &fileStat, char *perm);
    
    int main(int argc, char *argv[])
    {
        if (argc != 2)
        {
            cerr << "Usage: " << argv[0] << " <file-name>" << endl;
            exit(EXIT_FAILURE);
        }
    
        struct stat fileStat;
        if (lstat(argv[1], &fileStat) == -1)
            err_exit("lstat error");
    
        //获取权限
        char perm[11];
        filePerm(fileStat, perm);
        cout << perm << ' ';
    
        //获取文件链接数
        cout << fileStat.st_nlink << ' ';
    
        //获取文件所有者
        struct passwd *ps = getpwuid(fileStat.st_uid);
        cout << ps->pw_name << ' ';
    
        //获取文件所属组
        struct group *gp = getgrgid(fileStat.st_gid);
        cout << gp->gr_name << ' ';
    
        if (isDevice(fileStat))
            cout << major(fileStat.st_dev) << ", "
                 << minor(fileStat.st_rdev) << ' ';
        else
            cout << fileStat.st_size << ' ';
    
        // 打印最后一次修改时间
        time_t mtime = fileStat.st_mtime;
        struct tm *pTime = localtime(&mtime);
        cout << pTime->tm_mon+1 << "月 " << pTime->tm_mday << ' '
             << pTime->tm_hour << ':' << pTime->tm_min << ' ';
    
        // 打印文件名
        cout << argv[1];
        if (isLink(fileStat))
        {
            cout << " -> ";
            char name[1024] = {0};
            if (readlink(argv[1], name, sizeof(name)) == -1)
                err_exit("readlink error");
            cout << name;
        }
        cout << endl;
    
    }
    
    inline void err_exit(std::string message)
    {
        perror(message.c_str());
        exit(EXIT_FAILURE);
    }
    bool isDevice(const struct stat &fileStat)
    {
        switch(fileStat.st_mode & S_IFMT)
        {
        case S_IFBLK:
        case S_IFCHR:
            return true;
            break;
        default:
            return false;
            break;
        }
        return false;
    }
    bool isLink(const struct stat &fileStat)
    {
        if ((fileStat.st_mode & S_IFMT) == S_IFLNK)
            return true;
        return false;
    }
    void filePerm(const struct stat &fileStat, char *perm)
    {
        strcpy(perm, "----------");
        switch(fileStat.st_mode & S_IFMT)
        {
        case S_IFSOCK:
            perm[0] = 's';
            break;
        case S_IFLNK:
            perm[0] = 'l';
            break;
        case S_IFREG:
            perm[0] = '-';
            break;
        case S_IFBLK:
            perm[0] = 'b';
            break;
        case S_IFDIR:
            perm[0] = 'd';
            break;
        case S_IFCHR:
            perm[0] = 'c';
            break;
        case S_IFIFO:
            perm[0] = 'p';
            break;
        default:
            perm[0] = '?';
            break;
        }
    
        if (fileStat.st_mode & S_IRUSR)
            perm[1] = 'r';
        if (fileStat.st_mode & S_IWUSR)
            perm[2] = 'w';
        if (fileStat.st_mode & S_IXUSR)
            perm[3] = 'x';
        if (fileStat.st_mode & S_IRGRP)
            perm[4] = 'r';
        if (fileStat.st_mode & S_IWGRP)
            perm[5] = 'w';
        if (fileStat.st_mode & S_IXGRP)
            perm[6] = 'x';
        if (fileStat.st_mode & S_IROTH)
            perm[7] = 'r';
        if (fileStat.st_mode & S_IWOTH)
            perm[8] = 'w';
        if (fileStat.st_mode & S_IXOTH)
            perm[9] = 'x';
    }

  • 相关阅读:
    linux tar 压缩解压缩
    JS获取图片上传地址
    ipython notebook
    docker build lnmp(未完成。。。)
    centos6.7 install chrome
    centos6.6 install
    centos 安装mysqldb 记录
    centos emacs安装
    第三周-第08章节-Python3.5-文件修改详解
    第三周-第06章节-Python3.5-文件读与写详解
  • 原文地址:https://www.cnblogs.com/itrena/p/5926978.html
Copyright © 2011-2022 走看看