Stat(),Lstat(),Fstat() 获取文件/目录的相关信息

stat 的使用

Linux有个命令,ls -l,效果如下:

这个命令能显示文件的类型、操作权限、硬链接数量、属主、所属组、大小、修改时间、文件名。它是怎么获得这些信息的呢,请看下面的讲解。

stat 的基本使用

stat:返回一个与此命

需要包含的头文件: <sys/types.h>,<sys/stat.h>,<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() & lstat()来说path,是要查看属性的文件或目录的全路径名称

  对于fstat,fd 是要查看属性文件的文件描述符

  buf:指向用于存放文件属性的结构体,函数成功调用后,buf各个字段存放各个属性。

返回值 成:

  功返回0;      错误返回 -1;

给定一个文件:

  stat 函数获得一个与此命名文件有关的信息(到一个struct stat 类型的buf中) 。

  fstat 函数获得文件描述符 fd 打开文件的相关信息(到一个struct stat 类型的buf中) 。

  lstat 函数类似于 stat,但是当命名文件是一个符号连接时, lstat 获取该符号连接的有关信息,而不是由该符号连接引用文件的信息。

struct stat在系统头文件<stat.h>中,具体定义如下:

 1 struct stat    
 2 {    
 3     dev_t       st_dev;     /* ID of device containing file -文件所在设备的ID*/    
 4     ino_t       st_ino;     /* inode number -inode节点号*/  
 5     mode_t      st_mode;    /* Protection -文件的类型和存取的权限*/    
 6     nlink_t     st_nlink;   /* number of hard links -链向此文件的连接数(硬连接)*/    
 7     uid_t       st_uid;     /* user ID of owner -user id*/    
 8     gid_t       st_gid;     /* group ID of owner - group id*/    
 9     dev_t       st_rdev;    /* device ID (if special file) -设备号,针对设备文件*/    
10     off_t       st_size;    /* total size, in bytes -文件大小,字节为单位*/    
11     blksize_t   st_blksize; /* blocksize for filesystem I/O -系统块的大小*/     12     blkcnt_t    st_blocks;  /* number of blocks allocated -文件所占块数*/    
13     time_t      st_atime;   /* time of last access -最近存取时间*/    
14     time_t      st_mtime;   /* time of last modification -最近修改时间*/    
15     time_t      st_ctime;   /* time of last status change - */    
16 };  


st_mode是用特征位来表示文件类型以及操作权限的,特征位的定义如下:

 1 S_IFMT      0170000     文件类型的位遮罩
 2 S_IFSOCK    0140000     socket
 3 S_IFLNK     0120000     符号链接(symbolic link)
 4 S_IFREG     0100000     一般文件
 5 S_IFBLK     0060000     区块装置(block device)
 6 S_IFDIR     0040000     目录
 7 S_IFCHR     0020000     字符装置(character device)
 8 S_IFIFO     0010000     先进先出(fifo)
 9 S_ISUID     0004000     文件的(set user-id on execution)位
10 S_ISGID     0002000     文件的(set group-id on execution)位
11 S_ISVTX     0001000     文件的sticky位
12 S_IRWXU     00700       文件所有者的遮罩值(即所有权限值)
13 S_IRUSR     00400       文件所有者具可读取权限
14 S_IWUSR     00200       文件所有者具可写入权限
15 S_IXUSR     00100       文件所有者具可执行权限
16 S_IRWXG     00070       用户组的遮罩值(即所有权限值)
17 S_IRGRP     00040       用户组具可读取权限
18 S_IWGRP     00020       用户组具可写入权限
19 S_IXGRP     00010       用户组具可执行权限
20 S_IRWXO     00007       其他用户的遮罩值(即所有权限值)
21 S_IROTH     00004       其他用户具可读取权限
22 S_IWOTH     00002       其他用户具可写入权限
23 S_IXOTH     00001       其他用户具可执行权限

POSIX定义了下面几种通过st_mode判断文件类型的宏:

1 The following POSIX macros are defined to check the file type using the st_mode field:
2 S_ISREG(m)  /* is it a regular file? -普通文件 */
3 S_ISDIR(m)  /* directory? -目录文件? */
4 S_ISCHR(m)  /* character device? -字符设备文件? */
5 S_ISBLK(m)  /* block device? -块设备文件? */
6 S_ISFIFO(m) /* FIFO (named pipe)? -管道文件? */
7 S_ISLNK(m)  /* symbolic link? (Not in POSIX.1-1996.) -符号链接? */
8 S_ISSOCK(m) /* socket? (Not in POSIX.1-1996.) -套接口? */


1. stat()获取文件相关信息

 1 #include <stdio.h>
 2 #include <stat.h>
 3 #include <sys/types.h>
 4 #include <sys/stat.h>
 5 #include <unistd.h>
 6
 7 int main(int argc, char **argv)
 8 {
 9     struct stat     buf;
10     if(argc != 2) {
11        printf("Usage: stat ");
12        exit(-1);
13     }
14     if(stat(argv[1], &buf) != 0) {
15         printf("stat error.");
16         exit(-1);
17     }
18     printf("#i-node:    %ld\n", buf.st_ino);
19     printf("#link:      %d\n", buf.st_nlink);
20     printf("UID:        %d\n", buf.st_uid);
21     printf("GID:        %d\n", buf.st_gid);
22     printf("Size        %ld\n", buf.st_size);
23     exit(0);
24 }


2. 实现Linux ls命令

 1 #include <stdio.h>
 2 #include <dirent.h>
 3 #include <sys/types.h>
 4 #include <sys/stat.h>
 5 #include <unistd.h>
 6 #include <pwd.h>
 7 #include <grp.h>
 8 #include <time.h>
 9 #include <string.h>
10
11 char gettype(mode_t mod)
12 {
13     /*
14        if( S_ISREG(mod) ) return ‘-‘;
15        if( S_ISDIR(mod) ) return ‘d‘;
16        if( S_ISCHR(mod) ) return ‘c‘;
17        if( S_ISBLK(mod) ) return ‘b‘;
18        if( S_ISLNK(mod) ) return ‘l‘;
19        if( S_ISSOCK(mod) ) return ‘s‘;
20        if( S_ISFIFO(mod) ) return ‘p‘;
21        */
22     switch(mod & S_IFMT)
23     {
24     case S_IFSOCK: return ‘s‘;
25     case S_IFREG: return ‘-‘;
26     case S_IFCHR: return ‘c‘;
27     case S_IFBLK: return ‘b‘;
28     case S_IFLNK: return ‘l‘;
29     case S_IFIFO: return ‘p‘;
30     case S_IFDIR: return ‘d‘;
31     }
32 }
33
34 char *getperm(mode_t mod)
35 {
36     static char buf[10];
37
38     int i = 9;
39     while(i--)
40     {
41         if(mod & 1<<i)
42         {
43             switch((8-i)%3)
44             {
45             case 0: buf[8-i] = ‘r‘; break;// r/w/x;
46             case 1: buf[8-i] = ‘w‘; break;// r/w/x;
47             case 2: buf[8-i] = ‘x‘; break;// r/w/x;
48             }
49         }
50         else
51             buf[8-i] = ‘-‘;
52     }
53
54     return buf;
55 }
56
57 char *getttt(time_t *t)
58 {
59     static char buf[50];
60
61     strncpy(buf, ctime(t), 24);
62
63     return buf;
64 }
65
66 int main(int argc, char **argv)
67 {
68     DIR *dp = opendir((2==argc)?argv[1]:".");
69
70     if(2 == argc)
71         chdir(argv[1]);
72
73     struct dirent *p;
74
75     struct stat s;
76     while( p = readdir(dp) )
77     {
78         if(-1 == stat(p->d_name, &s) )
79         {
80             perror("stat");
81             return -1;
82         }
83
84         printf( "%c%s %5d %s %s %10ld %s\033[1;31;40m %s  \033[0m\n",
85                 gettype(s.st_mode),
86                 getperm(s.st_mode),
87                 s.st_nlink,
88                 getpwuid(s.st_uid)->pw_name,
89                 getgrgid(s.st_gid)->gr_name,
90                 s.st_size,
91                 getttt(&s.st_mtime),
92                 p->d_name );
93     }
94 }
时间: 2024-10-11 10:33:24

Stat(),Lstat(),Fstat() 获取文件/目录的相关信息的相关文章

Android 获取文件存储系统的相关信息

package com.mob.getsdandphone; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.lang.reflect.Method; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Li

第九篇:使用 lstat 函数获取文件信息

前言 在之前的文章中,描述过如何用 fcntl 函数改变文件的状态标记.但,文件还有很多信息,如文件类型,权限设置,设备编号,访问时间等等.如果要获取这些信息,则使用函数 lstat 可以轻松达到这个目的. 下面的程序将使用该函数获取文件类型信息并判断它的类型. 但在这之前,先要说明文件信息结构体和文件类型判定宏. 文件信息结构体 调用 lstat 函数将会把指定文件的信息存放到 stat 结构体中,这个结构体的定义大致如下: 文件类型判定宏 文件结构体中的文件类型字段是一个整数,对此,可以使用

linux 获取文件系统信息(磁盘信息)

源码如下: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/vfs.h> //文件系统信息结构体 struct fileSystem_info{ char fileSystem_format[8]; char fileSystem_total_capacity[11]; char fileSystem_free_capacity[11]; char fileSy

一个可以获取linux 系统硬件相关信息的类

<?php  class CServerInfo {     static public function getCpuData($speed = 0.5)     {         if (false === ($prevVal = @file("/proc/stat"))) return false;         $prevVal = implode($prevVal, PHP_EOL);         $prevArr = explode(' ', trim($pr

Linux3.0.0内核中客体(如文件/目录)相关的DAC安全数据结构(传统9Bit模块、ACL模式)

第1章           FCB数据结构(文件控制块) 1.  目录项 相当于FCB次部,包括两个内容: 即文件名和inode编号, 不同的文件名可能对应同一个inode编号,  这样便对应同一个FCB主部, 即一个文件可以有多个名字. 2.  inode 相当于FCB主部, 包括文件主.共享说明.地址信息等, 称为inode, inode与文件具有一对一的关系. 在UNIX文件系统中, 有一个固定的区域, 用于保存所有文件的inode.每个inode有一个唯一的编号,称为i_number.

iOS获取运营商的相关信息

1.导入:CoreTelephony.framework 2.添加头文件 #import <CoreTelephony/CTTelephonyNetworkInfo.h> #import <CoreTelephony/CTCarrier.h> 3.获取网络环境 -(void)networktype{ NSArray *subviews = [[[[UIApplication sharedApplication] valueForKey:@"statusBar"]

获取进程列表及相关信息

闲着没事,看着任务管理器好玩,查资料先简单实现一下,代码中没有加入获取CPU占用率的代码,这个代码网上很多,只是不喜欢那种写法,这里就不写了.以后继续完善,对于System Process和System的信息还没法获得,那位兄弟知道可以提个醒. 代码如下 [delphi] view plaincopy unit Main; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Form

【Android M】获取屏幕锁定的相关信息:“无”,“滑动”,“PIN码”,&quot;图案&quot;,&quot;密码&quot;

ENV: Android M 6.0.1 import android.os.UserHandle; import com.android.internal.widget.LockPatternUtils; import android.app.admin.DevicePolicyManager; LockPatternUtils mLockPatternUtils = new LockPatternUtils(mContext); int userId = UserHandle.myUserI

CentOS(九)--与Linux文件和目录管理相关的一些重要命令①

   接上一篇文章,实际生产过程中的目录管理一定要注意用户是root 还是其他用户. 一.目录与路径 1.相对路径与绝对路径 因为我们在Linux系统中,常常要涉及到目录的切换,所以我们必须要了解 "路径" 以及 "相对路径" 与 "绝对路径" 的概念. 在之前的学习中,就反复的强调了Linux的目录是 "树状目录" .假设我们需要在任意一个目录下切换到另一个目录下,通常是使用的是 cd 这个命令,此时在写切换的目录名时就有两