文件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‘;
}

时间: 2024-10-22 09:58:29

文件I/O实践(2) --文件stat的相关文章

轻度破解EXE文件的最近实践

在经历股市多年的大起大落.大赚大赔之后,痛定思痛,深切感到在金融市场拼搏,必须建立健全交易纪律守则,严格执行. 这套完整的纪律守则,就是"交易系统".在许多方面,它与一般的专家系统相近似. 专家系统的最佳开发工具,是Erlang下的Eresye.它的缺点是,其他语言如C.Python对它的调用不方便. 如果主程序是C或Python,一般需将Eresye做成服务器,通过sockets通讯调用,比较麻烦. 在简单实用方面,Prolog是第二佳的开发工具.如果只采用其推理机功能,Visual

数据结构实践——操作文件

本文是针对[数据结构基础系列(11):文件]中的实践项目. [项目1]操作文件 有若干学生的成绩数据如下,将这些数据保存到st数组中: 学号 姓名 年龄 性别 语文 数学 英语 1 陈华 20 男 78 90 84 5 张明 21 男 78 68 92 8 王英 20 女 86 81 86 3 刘丽 21 女 78 92 88 2 许可 20 男 80 83 78 4 陈军 20 男 78 88 82 7 马胜 21 男 56 67 75 基于这些数据,编程序实现下面的功能: (1)将st数组中

数据结构实践——索引文件

本文是针对[数据结构基础系列(11):文件]中的实践项目. [项目]索引文件 有若干学生的成绩数据如下,将这些数据保存到st数组中: 学号 姓名 年龄 性别 语文 数学 英语 1 陈华 20 男 78 90 84 5 张明 21 男 78 68 92 8 王英 20 女 86 81 86 3 刘丽 21 女 78 92 88 2 许可 20 男 80 83 78 4 陈军 20 男 78 88 82 7 马胜 21 男 56 67 75 6 曾强 20 男 78 89 82 基于这些数据,编程序

Linux系统中有关/dev/null和/dev/zero文件说明及实践

Linux系统中有关/dev/null和/dev/zero文件说明 提示:这个题目完全可以作为一个面试题考考运维的应聘者: 面试题:请解释Linux中/dev/null和/dev/zero两个文件的作用和区别. 在类Unix操作系统中,设备节点并不一定要对应物理设备.没有这种对应关系的设备被称之为伪设备.操作系统运用了它们实现多种多样的功能,/dev/null和/dev/zero就是这样的设备,类似的还有/dev/urandom./dev/tty等. 先检查下/dev/null和/dev/zer

SaltStack 之 salt-cp 文件复制替换实践

SaltStack 之 salt-cp 文件复制替换实践 一.我们把/srv/salt/files/hosts 文件复制到各从机的的/root下 [[email protected] srv]# salt-cp '*' /srv/salt/files/hosts /root/ {'BackupServer': {'/root/hosts': True}, 'GZ15_ZABBIX': {'/root/hosts': True}, 'GZIFC_ZABBIX': {'/root/hosts': T

C语言多文件程序小实践

因为老师要求用TC所以是在TC上运行……因为上课讲的课下就忘了: 虽然老师用的是2.0,以下是在TC3.0上运行的,记下来以免哪天又记忆损伤 [主文件-cwww1.cpp] ↑主文件:a,b,c为全局变量,plus为全局函数,文件名:cww1.cpp [函数文件-cwww2.cpp] ↑文件2:extern那个可以无视……写不写都一样,文件名:cww2.cpp [project文件-cwww.prj] ↑project文件:用于存放前两个文件,格式:#include "(文件名)",一

文件I/O实践(1) --基础API

什么是I/O 输入/输出是内存和外设之间拷贝数据的过程: 设备->内存: 输入操作 内存->设备: 输出操作 高级I/O: ANSI C提供的标准I/O库函数成为高级I/O, 也称为带缓冲的I/O; 低级I/O: Linux 提供的系统调用, 通常也称为不带缓冲的I/O; 文件描述符 对于Linux内核而言, 所有的文件或设备都对应一个文件描述符(Linux的设计哲学: 一切皆文件), 这样可以简化系统编程的复杂程度; 当打开/创建一个文件的时候, 内核向进程返回一个文件描述符(是一个非负整数

Linux下恢复误删文件:思路+实践

周五篮球群里有人问误删文件了怎么恢复,得知是ext4文件系统之后我推荐了ext4magic这个工具,然后又有人提到了xfs的话怎么办,正好前几天看到Dave Chinner在邮件列表里提到了这个问题,他推荐的工具是xfs_irecover.这里就稍微总结一下Linux下误删文件如何恢复. 1. 当发现误删了文件之后,立即把文件系统卸载掉,或者remount成ro状态,就是不要再写了,让数据不要被其他数据覆盖.因为大部分文件系统在删除文件的时候只是把这个文件标记成删除,把文件所使用的数据块标记成可

Linux文件权限与文件夹权限实践

文件权限在基础中有介绍,不在重复 一.文件夹权限: 示例: 解释说明: r --read 既ls w --write     既创建新的目录或者文件 x --execute 既cd 现在有4个用户分属3个不同的用户组,如下: 1  2 3 4 现在开始测试文件夹权限: (1).r权限测试 other: 同用户组: oldboy为该文件夹用户,root为特殊用户所以都有r权限 (2).x权限测试 (3).w权限测试 可以看出同group其他用户和other都不具有w权限 同group oldgri