linux系统编程之文件与I/O(四):文件的属性

来源:互联网 发布:微信拼图游戏源码 编辑:程序博客网 时间:2024/06/05 17:00

一、读取文件元数据

int stat(const char *path, struct stat *buf);int fstat(int fd, struct stat *buf);int lstat(const char *path, struct stat *buf);

stat() stats the file pointed to by path and fills in buf.
lstat() is identical to stat(), except that if path is a symbolic link, then the link itself is stat-ed, not the file that it refers to.
fstat() is identical to stat(), except that the file to be stat-ed is specified by the file descriptor 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 file system I/O */blkcnt_t  st_blocks;  /* number of 512B blocks allocated */time_t    st_atime;   /* time of last access */  readtime_t    st_mtime;   /* time of last modification */  writetime_t    st_ctime;   /* time of last status change */ chmod/chown};

示例程序:

/*************************************************************************    > File Name: file_stat.c    > Author: Simba    > Mail: dameng34@163.com    > Created Time: Sat 23 Feb 2013 02:34:02 PM CST ************************************************************************/#include<sys/types.h>#include<sys/stat.h>#include<unistd.h>#include<fcntl.h>#include<stdio.h>#include<stdlib.h>#include<errno.h>#include<string.h>#define ERR_EXIT(m) \    do { \        perror(m); \        exit(EXIT_FAILURE); \    } while(0)#define MAJOR(a) (int)((unsigned short)a >> 8)  // 高8位,主设备号#define MINOR(a) (int)((unsigned short)a & 0xFF)int filetype(struct stat *buf){    int flag = 0;    printf("Filetype:");    mode_t mode;    mode = buf->st_mode;    switch (mode & S_IFMT)    {    case S_IFSOCK:        printf("socket\n");        break;    case S_IFLNK:        printf("symbolic link\n");        break;    case S_IFREG:        printf("regular file\n");        break;    case S_IFBLK:        printf("block device\n");        flag = 1;        break;    case S_IFDIR:        printf("directory\n");        break;    case S_IFCHR:        printf("character device\n");        flag = 1;        break;    case S_IFIFO:        printf("FIFO\n");        break;    default:        printf("unknown file type\n");        break;    }    return flag;}void fileperm(struct stat *buf, char perm[]){    strcpy(perm, "----------");    perm[0] = '?';    mode_t mode;    mode = buf->st_mode;    switch (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;    }    if (mode & S_IRUSR)        perm[1] = 'r';    if (mode & S_IWUSR)        perm[2] = 'w';    if (mode & S_IXUSR)        perm[3] = 'x';    if (mode & S_IRGRP)        perm[4] = 'r';    if (mode & S_IWGRP)        perm[5] = 'w';    if (mode & S_IXGRP)        perm[6] = 'x';    if (mode & S_IROTH)        perm[7] = 'r';    if (mode & S_IWOTH)        perm[8] = 'w';    if (mode & S_IXOTH)        perm[9] = 'x';    perm[10] = '\0';}int main(int argc, char *argv[]){    if (argc != 2)    {        fprintf(stderr, "Usage %s file\n", argv[0]);        exit(EXIT_FAILURE);    }    printf("Filename:%s\n", argv[1]);    struct stat sbuf;    if (lstat(argv[1], &sbuf) == -1)        ERR_EXIT("stat error");    printf("file in Dev number:major %d, minor %d\n",           MAJOR(sbuf.st_dev), MINOR(sbuf.st_dev));    printf("File inode:%d\n", (int) sbuf.st_ino);    if (filetype(&sbuf))    {        printf("Device number:major %d, minor %d\n",               MAJOR(sbuf.st_rdev), MINOR(sbuf.st_rdev));    }    char perm[11] = {0};    fileperm(&sbuf, perm);    printf("File permission bits=%o %s\n", sbuf.st_mode & 0777, perm);  // 0777 是八进制数    return 0;}

测试如下:
simba@ubuntu:~/Documents/code/linux_programming/APUE/File_IO$ ./file_stat Makefile
Filename:Makefile
file in Dev number:major 8, minor 1
File inode:660022
Filetype:regular file
File permission bits=664 -rw-rw-r–
因为是普通文件,故从st_dev字段看设备号,而不是st_rdev. 主设备号表示设备驱动程序,而次设备号表示特定的子设备。比如在同一个磁盘上面不同的文件系统,设备驱动程序相当,但是次设备号不同。
st_rdev只有字符特殊文件和块特殊文件才有这个值,表示实际设备的设备编号。
The st_dev value for every filename on a system is the device number of the file system containing that filename and its corresponding
i-node.
Only character special files and block special files have an st_rdev value. This value contains the device number for the actual device.

#include "apue.h"#ifdef SOLARIS#include <sys/mkdev.h>#endifint main(int argc, char *argv[]){    int i;    struct stat buf;    for (i = 1; i < argc; i++)    {        printf("%s: ", argv[i]);        if (stat(argv[i], &buf) < 0)        {            err_ret("stat error");            continue;        }        printf("dev = %d/%d", major(buf.st_dev), minor(buf.st_dev));        if (S_ISCHR(buf.st_mode) || S_ISBLK(buf.st_mode))        {            printf(" (%s) rdev = %d/%d",                   (S_ISCHR(buf.st_mode)) ? "character" : "block",                   major(buf.st_rdev), minor(buf.st_rdev));        }        printf("\n");    }    exit(0);}

./a.out//home/sar/dev/tty[01]/:dev=3/3/home/sar:dev=3/4/dev/tty0:dev=0/7(character)rdev=4/0/dev/tty1:dev=0/7(character)rdev=4/1 mount which directories are mounted on which devices?
/dev/hda3 on / type ext2 (rw,noatime)
/dev/hda4 on /home type ext2 (rw,noatime)
$ ls -lL /dev/tty[01] /dev/hda[34]
brw——- 1 root 3, 3 Dec 31 1969 /dev/hda3
brw——- 1 root 3, 4 Dec 31 1969 /dev/hda4
crw——- 1 root 4, 0 Dec 31 1969 /dev/tty0
crw——- 1 root 4, 1 Jan 18 15:36 /dev/tty1

Note that the filenames and i-nodes for the two terminal devices (st_dev) are on device 0/7 the devfs pseudo file system, which implements the /dev but that their actual device numbers are 4/0 and 4/1.

参考:《APUE》
http://infohost.nmt.edu/~eweiss/222_book/222_book/0201433079/ch04lev1sec23.html

转载自http://blog.csdn.net/jnu_simba/article/details/8921110

0 0
原创粉丝点击