首页 > 代码库 > 文件属性

文件属性

一.Linux中各种文件类型
    1.普通文件(文件标识是:-)
        (1)文本文件。文件的内容是由文本构成的,文本指的是ASCII码字符。文件里的内容本质上都是数字,而文件中的数字本身应该被理解为这个数字对应的ASCII码。常见的.c文件,.h文件,.txt文件等都是文本文件。
        (2)二进制文件。二进制文件中存储的本质上也是数字,只不过这些数字并不是文字的编码数字,而就是真正的数字。
        (3)怎么区分一个文件是文本文件还是二进制文件?在Linux系统层面是不区分这2个的
        
    2.目录文件(文件标识是:d)
        (1)目录就是文件夹,文件夹在Linux中也是一种文件,不过是特殊文件。用vi打开一个文件夹就能看到,文件夹里面存的内容包括这个文件的路径,还有文件夹里面的文件列表。
        (2)但是文件夹这种文件比较特殊,本身并不适合用普通的方式来读写。Linux中是使用特殊的一些API来专门读写文件夹的。
    3.字符设备文件(文件标识是:c)
        (1)设备文件对应的是硬件设备,也就是说这个文件虽然在文件系统中存在,但是并不是真正存在于硬盘上的一个文件,而是文件系统虚拟制造出来的(叫虚拟文件系统,如/dev/sys/proc等)
        (2)虚拟文件系统中的文件大多数不能或者说不用直接读写,而是用一些特殊的API产生或者使用的,具体在驱动阶段会详解。
    4.块设备文件(文件标识是:b)
    5.管道文件(文件标识是:p)
    6.套接字文件(文件标识是:s)
    7.符号链接文件(文件标识是:l)
二.常用文件属性获取
    1.stat、fstat、lstat函数简介
        (1)每个文件都附带了这个文件的一些属性,属性是存在于文件本身中的,不能直接打开看到,属性信息只能被专用的API打开看到
        (2)这三个函数就是来查看文件属性的API,三个作用一样,参数不用。
        (3)Linux命令行下可以使用stat命令来查看文件属性。stat xxx(man 1 stat查看手册)实际上还是使用stat系统调用来实现的。
        (4)3个系统调用函数的原型
       #include <sys/types.h>
       #include <sys/stat.h>
       #include <unistd.h>    
       int stat(const char *path, struct stat *buf);    //buf表示传入一个stat结构体指针,函数执行后将文件属性放入这个结构体中
       int fstat(int fd, struct stat *buf);
       int lstat(const char *path, struct stat *buf);
        (5)stat、fstat的区别是:stat是从文件名得到文件属性,而fstat是从一个已经打开的文件fd得到文件的属性。stat是从磁盘去读取文件的,而fstat是从内存读取动态文件的。
        (6)lstat和stat/fstat的差别是:对于符号链接文件,stat和fstat查阅的是符号链接文件执行的文件的属性,而lstat查阅的是符号链接文件本身的属性。
    2.struct stat结构体
        (1)struct stat结构体是内核定义的,里面存放的就是文件的属性信息。在<sys/stat.h>头文件中声明
  1. struct stat {
  2. dev_t st_dev; /* ID of device containing file 文件所在设备ID*/
  3. ino_t st_ino; /* inode number Inode节点编号*/
  4. mode_t st_mode; /* protection 文件类型和相关权限*/
  5. nlink_t st_nlink; /* number of hard links 硬链接个数*/
  6. uid_t st_uid; /* user ID of owner 所有者用户ID*/
  7. gid_t st_gid; /* group ID of owner 所有者组ID*/
  8. dev_t st_rdev; /* device ID (if special file) 设备ID(如果是特殊文件)*/
  9. off_t st_size; /* total size, in bytes 文件大小,以字节为单位*/
  10. blksize_t st_blksize; /* blocksize for filesystem I/O 文件系统I/O块大小*/
  11. blkcnt_t st_blocks; /* number of 512B blocks allocated 已分配块(512B)个数*/
  12. time_t st_atime; /* time of last access 上次访问时间*/
  13. time_t st_mtime; /* time of last modification 上次更新时间(内容)*/
  14. time_t st_ctime; /* time of last status change 上次状态更新时间(属性、状态、权限等)*/
  15. };
  16. st_dev: unsigned long
  17. st_ino: unsigned long
  18. st_mode: unsigned short
  19. st_nlink: unsigned short
  20. st_uid: unsigned short
  21. st_gid: unsigned short
  22. st_rdev: unsigned long
  23. st_size: unsigned long
  24. st_blksize: unsigned long
  25. st_blocks: unsigned long
  26. st_atime: unsigned long
  27. st_mtime: unsigned long
  28. st_ctime: unsigned long
三.stat函数的应用案例
    1.用代码判断文件类型
        (1)文件类型就是-、d、c、b等
        (2)文件属性中文件类型标志在struct stat结构体的mode_t st_mode元素中,这个元素其实就是一个按位来定义的一个位标志,Linux中定义了很多宏可以用来测试是哪个标志。
            这些宏的返回值如果是1表示是,返回0就表示否
            S_ISREG(m)  is it a regular file?
                是否是普通文件
            S_ISDIR(m)  directory?
                目录
            S_ISCHR(m)  character device?
                字符设备文件
            S_ISBLK(m)  block device?
                块设备文件
            S_ISFIFO(m) FIFO (named pipe)?
                FIFO管道文件
            S_ISLNK(m)  symbolic link?  (Not in POSIX.1-1996.)
                链接文件
            S_ISSOCK(m) socket?  (Not in POSIX.1-1996.)
                套接字文件
    2.用代码判断文件权限设置
        (1)st_mode中除了记录了文件类型外,还有文件权限
        (2)Linux并没有给文件权限测试提供宏操作,而是只提供了位掩码,所以需要自己用位掩码来判断是否具有相应的权限
           S_IFMT     0170000   bit mask for the file type bit fields
           S_IFSOCK   0140000   socket
           S_IFLNK    0120000   symbolic link
           S_IFREG    0100000   regular file
           S_IFBLK    0060000   block device
           S_IFDIR    0040000   directory
           S_IFCHR    0020000   character device
           S_IFIFO    0010000   FIFO
           S_ISUID    0004000   set-user-ID bit
           S_ISGID    0002000   set-group-ID bit (see below)
           S_ISVTX    0001000   sticky bit (see below)
           S_IRWXU    00700     mask for file owner permissions
           S_IRUSR    00400     owner has read permission
           S_IWUSR    00200     owner has write permission
           S_IXUSR    00100     owner has execute permission
           S_IRWXG    00070     mask for group permissions
           S_IRGRP    00040     group has read permission
           S_IWGRP    00020     group has write permission
           S_IXGRP    00010     group has execute permission
           S_IRWXO    00007     mask for permissions for others (not in group)
           S_IROTH    00004     others have read permission
           S_IWOTH    00002     others have write permission
           S_IXOTH    00001     others have execute permission
    
  1. #include <stdio.h>
  2. #include <sys/types.h>
  3. #include <sys/stat.h>
  4. #include <unistd.h>
  5. #include <string.h>
  6. #define NAME "test.text"
  7. int main(int argc , char *argv[])
  8. {
  9. struct stat st;
  10. memset(&st,0,sizeof(st));
  11. stat(NAME,&st);
  12. printf("st_dev = %d\n",st.st_dev);
  13. printf("st_ino = %d\n",st.st_ino);
  14. printf("st_mode = %d\n",st.st_mode);
  15. printf("st_nlink = %d\n",st.st_nlink);
  16. printf("st_uid = %d\n",st.st_uid);
  17. printf("st_gid = %d\n",st.st_gid);
  18. printf("st_rdev = %d\n",st.st_rdev);
  19. printf("st_size = %d\n",st.st_size);
  20. printf("st_blksize = %d\n",st.st_blksize);
  21. printf("st_blocks = %d\n",st.st_blocks);
  22. printf("st_atime = %d\n",st.st_atime);
  23. printf("st_mtime = %d\n",st.st_mtime);
  24. printf("st_ctime = %d\n",st.st_ctime);
  25. //运行后的结果//
  26. /* st_dev = 27
  27. st_ino = 152
  28. st_mode = 33279
  29. st_nlink = 1
  30. st_uid = 0
  31. st_gid = 0
  32. st_rdev = 0
  33. st_size = 26
  34. st_blksize = 1024
  35. st_blocks = 1
  36. st_atime = 1479045535
  37. st_mtime = 1479046813
  38. st_ctime = 1479046813 */
  39. /**st_mode中有一些宏可以用来判断文件的类型,也有权限相关的宏**/
  40. int ret = S_ISREG(st.st_mode);
  41. printf("是否是普通文件:%d\n",ret);
  42. /**判断文件的权限**/
  43. ret = (S_IRWXU & st.st_mode)>>8; //S_IRWXU对应的掩码是00700,因此要右移8位
  44. printf("读写可执行权限:%d\n",ret);
  45. return 0;
  46. }



来自为知笔记(Wiz)


文件属性