当前位置:   article > 正文

Linux系统调用 - 获取文件状态 (stat, lstat和fstat)_获取文件信息的系统调用及stat()和读取目录的使用方法

获取文件信息的系统调用及stat()和读取目录的使用方法

获取文件状态的系统调用有三个,分别是stat,fstat和lstat,其实他们的作用是一样的,都是查询某个文件的状态。如果查询成功,会把文件状态的信息填充在一个stat结构体中。他们的函数定义分别如下:

  1. int stat(const char *path, struct stat *buf);
  2. int fstat(int fd, struct stat *buf);
  3. int lstat(const char *path, struct stat *buf);

可以看到,这三个系统调用用于输出的参数类型是一样的,都是struct stat,其中,state与fstat的区别在于,stat()用文件名来指定要查询的文件,而fstat()用文件描述符来指定目标文件;而stat()与lstat()的区别在于,如果指定的文件是一个符号链接,那么stat会解引用,查询该链接指向的普通文件的属性,而lstat()在遇到符号链接文件是,不去解引用,而是直接返回这个符号链接文件本身的属性。要成功获取到指定文件的状态信息,需要用户对文件存储位置的每一层目录都具有执行和读取权限。

Linux的系统调用中还有很多类似的以 f 和 l 开头的系统调用,他们的区别与作用和stat系列函数都是类似的。

 

返回参数struct stat的结构定义与各字段的含义分别为:

  1. struct stat {
  2. dev_t st_dev; /* 文件存放的设备ID */
  3. ino_t st_ino; /* 索引节点号 */
  4. mode_t st_mode; /* 文件的属性掩码 */
  5. nlink_t st_nlink; /* 硬链接的数量 */
  6. uid_t st_uid; /* 文件拥有者的用户ID */
  7. gid_t st_gid; /* 文件拥有者的组ID */
  8. dev_t st_rdev; /* 设备ID,仅对部分特殊文件有效 */
  9. off_t st_size; /* 文件大小,单位字节,软连接文件的大小是链接名长度 */
  10. blksize_t st_blksize; /* 文件使用的存储块大小 */
  11. blkcnt_t st_blocks; /* 文件占用的存储块数量,以512字节为单位 */
  12. time_t st_atime; /* 最后一次访问的时间 */
  13. time_t st_mtime; /* 最后一次内容修改的时间 */
  14. time_t st_ctime; /* 最后一次状态变化的时间 */
  15. };

对于st_mode字段,系统定义了一些宏来检查文件的类型:

           S_ISREG(m)  检查是否是常规文件

           S_ISDIR(m)  检查是否是目录

           S_ISCHR(m)  检查是否是字符设备 (如键盘)

           S_ISBLK(m)  检查是否是块设备(如硬盘)

           S_ISFIFO(m) 是否是命名管道

           S_ISLNK(m)  是否是符号链接

           S_ISSOCK(m) 是否是套接字

与其他的很多系统调用一样,这几个系统调用都是成功是返回0,否则返回-1,并设置对应的errno,常见的可能出现的errno有:
       EACCES:目标文件所在的目录或某个上级目录没有查找权限

      EBADF:指定的文件描述符无效.

       EFAULT:无效的文件地址

       ELOOP:可能遇到了循环引用的软链接文件

       ENAMETOOLONG:文件路径名太长.

       ENOENT:目录或文件不存在

       ENOMEM:内核内存耗尽

       ENOTDIR:指定的文件路径上,某个部分不是目录

       EOVERFLOW:引用的文件太大了,或者使用的索引节点太多了,或者占用的存储块太多了。

 

 

如下是使用stat()系统调用的演示程序:       

  1. #include <sys/types.h>
  2.        #include <sys/stat.h>
  3.        #include <time.h>
  4.        #include <stdio.h>
  5.        #include <stdlib.h>
  6.        int
  7.        main(int argc, char *argv[])
  8.        {
  9.            struct stat sb;
  10.            if (argc != 2) {
  11.                fprintf(stderr, "Usage: %s <pathname>\n", argv[0]);
  12.                exit(EXIT_FAILURE);
  13.            }
  14.            if (stat(argv[1], &sb) == -1) {
  15.                perror("stat");
  16.                exit(EXIT_FAILURE);
  17.            }
  18.            printf("File type:                ");
  19. switch (sb.st_mode & S_IFMT) {
  20.            case S_IFBLK:  printf("block device\n");            break;
  21.            case S_IFCHR:  printf("character device\n");        break;
  22.            case S_IFDIR:  printf("directory\n");               break;
  23.            case S_IFIFO:  printf("FIFO/pipe\n");               break;
  24.            case S_IFLNK:  printf("symlink\n");                 break;
  25.            case S_IFREG:  printf("regular file\n");            break;
  26.            case S_IFSOCK: printf("socket\n");                  break;
  27.            default:       printf("unknown?\n");                break;
  28.            }
  29.            printf("I-node number:            %ld\n", (long) sb.st_ino);
  30.            printf("Mode:                     %lo (octal)\n",
  31.                    (unsigned long) sb.st_mode);
  32.            printf("Link count:               %ld\n", (long) sb.st_nlink);
  33.            printf("Ownership:                UID=%ld   GID=%ld\n",
  34.                    (long) sb.st_uid, (long) sb.st_gid);
  35.            printf("Preferred I/O block size: %ld bytes\n",
  36.                    (long) sb.st_blksize);
  37.            printf("File size:                %lld bytes\n",
  38.                    (long long) sb.st_size);
  39.            printf("Blocks allocated:         %lld\n",
  40.                    (long long) sb.st_blocks);
  41.            printf("Last status change:       %s", ctime(&sb.st_ctime));
  42.            printf("Last file access:         %s", ctime(&sb.st_atime));
  43.            printf("Last file modification:   %s", ctime(&sb.st_mtime));
  44.            exit(EXIT_SUCCESS);
  45.        }

 

==================== 以下是广告 ====================

更多系统详尽的Linux系统编程内容,欢迎订阅GitChat专栏 《攻克Linux系统编程》

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/278467?site
推荐阅读
相关标签
  

闽ICP备14008679号