C语言中fstat、stat和lstat 区别

在写应用程序的时候发现我们经常回去检测一个文件的大小,有了大小才能映射这个文件到内存上,方便我们直接操作。

在介绍三者的区别之前,首先介绍的是一个非常重要的结构体类型,名字叫做struct stat,这是一个保存文件状态信息的结构体,其类型如下:

struct stat 

    dev_t     st_dev;     /* 文件所在设备的标识  */ 
     ino_t     st_ino;     /* 文件结点号  */ 
   mode_t    st_mode;    /* 文件保护模式  */ 
   nlink_t   st_nlink;   /* 硬连接数  */ 
   uid_t     st_uid;     /* 文件用户标识  */ 
   gid_t     st_gid;     /* 文件用户组标识  */ 
   dev_t     st_rdev;    /* 文件所表示的特殊设备文件的设备标识  */ 
   off_t     st_size;    /* 总大小,字节为单位  */ 
   blksize_t st_blksize; /* 文件系统的块大小  */ 
   blkcnt_t  st_blocks;  /* 分配给文件的块的数量,512字节为单元  */ 
   time_t    st_atime;   /* 最后访问时间  */ 
   time_t    st_mtime;   /* 最后修改时间  */ 
   time_t    st_ctime;   /* 最后状态改变时间  */ 
}; 

tips:这里需要注意的是st_mode这个域不像其他域那么容易使用,需要一些宏予以配合。实际上这些宏就是一些特定位置为1的二进制数的绰号,我们使用它们和st_mode进行”&”操作,从而就可以得到某些特定的信息。 

文件类型标志包括:
S_IFBLK:文件是一个特殊的块设备
S_IFDIR:文件是一个目录
S_IFCHR:文件是一个特殊的字符设备
S_IFIFO:文件是一个FIFO设备
S_IFREG:文件是一个普通文件
S_IFLNK:文件是一个符号链接

其他模式标志包括:
S_ISUID:文件设置了SUID位
S_ISGID:文件设置了SGID位
S_ISVTX:文件设置了sticky位

用于解释st_mode标志的掩码包括:
S_IFMT:文件类型
S_IRWXU:属主的读/写/执行权限,可以分成S_IXUSR, S_IRUSR, S_IWUSR
S_IRWXG:属组的读/写/执行权限,可以分成S_IXGRP, S_IRGRP, S_IWGRP
S_IRWXO:其他用户的读/写/执行权限,可以分为S_IXOTH, S_IROTH, S_IWOTH

还有一些用于帮助确定文件类型的宏定义,这些和上面的宏不一样,这些是带有参数的宏,类似与函数的使用方法:

S_ISBLK:测试是否是特殊的块设备文件
S_ISCHR:测试是否是特殊的字符设备文件
S_ISDIR:测试是否是目录
S_ISFIFO:测试是否是FIFO设备
S_ISREG:测试是否是普通文件
S_ISLNK:测试是否是符号链接
S_ISSOCK:测试是否是socket

fstat/stat/lstat系统调用
    
功能描述:   
获取一些文件相关的信息。 
  
用法:   
#include <sys/types.h> 
#include <sys/stat.h> 
#include <unistd.h> 

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

int fstat(int filedes, struct stat *buf); 
int lstat(const char *path, struct stat *buf); 
参数:   
path:文件路径名。 
filedes:文件描述词。 
buf:保存文件信息的结构体 
返回说明:   
成功执行时,返回0。失败返回-1,errno被设为以下的某个值   
EBADF:  文件描述词无效 
EFAULT: 地址空间不可访问 
ELOOP:  遍历路径时遇到太多的符号连接 
ENAMETOOLONG:文件路径名太长 
ENOENT:路径名的部分组件不存在,或路径名是空字串 
ENOMEM:内存不足 
ENOTDIR:路径名的部分组件不是目录  
下面放大的部分是他们的区别:
 fstat区别于另外两个系统调用的地方在于,fstat系统调用接受的是 一个“文件描述符”,而另外两个则直接接受“文件全路径”。文件描述符是需要我们用open系统调用后才能得到的,而文件全路经直接写就可以了。

stat和lstat的区别:当文件是一个符号链接时,lstat返回的是该符号链接本身的信息;而stat返回的是该链接指向的文件的

下面用一个例子还说明:

这个file文件是我自己随便写的一个文件,可以是任何文件,但是要有可读权限。

时间: 2024-09-20 06:04:34

C语言中fstat、stat和lstat 区别的相关文章

C语言中char*和char[]用法区别分析_C 语言

本文实例分析了C语言中char* 和 char []的区别.分享给大家供大家参考之用.具体分析如下: 一般来说,很多人会觉得这两个定义效果一样,其实差别很大.以下是个人的一些看法,有不正确的地方望指正. 本质上来说,char *s定义了一个char型的指针,它只知道所指向的内存单元,并不知道这个内存单元有多大,所以: 当char *s = "hello";后,不能使用s[0]='a':语句进行赋值.这是将提示内存不能为"written". 当用char s[]=&q

c语言中getch,getche,getchar的区别_C 语言

getchar 是stdio.h中的库函数,它的作用是从stdin流中读入一个字符,也就是说 ,如果stdin有数据的话不用输入就可以直接读取了.而getch()和getche()是conio.h中的库函数,它的作用是从键盘接收字符. getch() 实际是一个输入命令,作用是从键盘接收一个字符,而且并不把这个字符显示出来,就是说,你按了一个键后它并不在屏幕上显示你按的什么,而继续运行后面的代码,所以我们在C++中可以用它来实现"按任意键继续"的效果,即程序中遇到getch();这行语

Go语言中new()和 make()的区别详解_Golang

概述 Go 语言中的 new 和 make 一直是新手比较容易混淆的东西,咋一看很相似.不过解释两者之间的不同也非常容易. new 的主要特性 首先 new 是内建函数,你可以从 http://golang.org/pkg/builtin/ 这儿看到它,它的定义也很简单: 复制代码 代码如下: func new(Type) *Type 官方文档对于它的描述是: 复制代码 代码如下: 内建函数 new 用来分配内存,它的第一个参数是一个类型,不是一个值,它的返回值是一个指向新分配类型零值的指针 根

C语言中printf(),sprintf(),scanf(),sscanf()的用法和区别

以下是对C语言中printf(),sprintf(),scanf(),sscanf()的用法以及区别进行了详细的分析介绍,需要的朋友可以参考下   printf语法: #include <stdio.h> int printf( const char *format, ... ); printf()函数根据format(格式)给出的格式打印输出到STDOUT(标准输出)和其它参数中.返回值是输出的字符数量.sprintf语法: #include <stdio.h> int spri

如何解决:输入输出-c语言中&amp;amp;#39; &amp;amp;#39;,与&amp;amp;#39; &amp;amp;#39;的区别?

问题描述 c语言中' n',与' '的区别? 今天没事写了段代码. #include main() { int c; while(c=getchar())!='n' putchar(c); } 这里只能输入输出一次,就退出循环了. 而我这样写 将while(c=getchar())!='n'改为while(c=getchar())!='' 这样就可以多次循环输入输出了而我又将上面的改为while(c=getchar())!=EOF 则不能输出了. 请问这几个是为什么? 谢谢! 解决方案 首位是n

java语言中for循环和while循环有什么区别?

问题描述 java语言中for循环和while循环有什么区别? java语言中for循环和while循环有什么区别?一般应聘的公司用哪个比较多?是不是不会while循环也没事. 解决方案 是的,两个没什么区别.就好比一个肾也能活.虽然一般应聘的公司的程序员都有两个肾,但是如果你卖掉一个也没事. 解决方案二: 跳出while/for循环 for(xx;xx;xx){ ? ?? break ;//跳出for循环 ? } ? ? while(){ ? ??? break;跳出while循环 ? } =

c语言基础-c语言中a+=b和a=a+b有什么区别

问题描述 c语言中a+=b和a=a+b有什么区别 c语言中a+=b和a=a+b有什么区别,初学者求答案!不甚感激, 解决方案 a+=b是a = a + b的特例,前者中加法的一个加数和结果必须相同.后者不受限制. a = a + b a = b + a a = a + a a = a + 1 这些情况都可以用 += 代替. 但是 a = b + c 就不可以. 编译器为这两者产生的机器代码是一样的,可以视为等价. 高级语言,实现相同的功能,往往有不止一个语句或者运算符,这种现象也叫做"语法糖&q

C语言中NSInteger,NSNumber以及Int的区别

NSInteger和NSNumber   首先:NSInteger,NSNumber并没有什么关系,更不要想当然的以为二者还有什么继承关系,甚至还有人问NSInteger是不是NSNumber的子类?答案当然是NO!!!NSInteger只是一个基本的数据类型,而NSNumber是OC的对象,并且NSNumber继承自NSValue,NSValue又继承自NSObject. 既然 NSInteger是基本类型,那么,使用起来就非常简单. 声明一个变量, NSInteger myInt: 直接赋值

C语言中char* 和 char []区别

原文:C语言中char* 和 char []区别 想要把丢掉的东西捡起来,还是很辛苦啊,今天我就发现,我连char* 和 char []的区别都不知道. 很多人觉得这两个定义效果一样,其实差别很大.以下是个人的一些看法,有不正确的地方望指正. 本质上来说,char *s定义了一个char型的指针,它只知道所指向的内存单元,并不知道这个内存单元有多大,所以:当char *s = "hello";后,不能使用s[0]='a':语句进行赋值.这是将提示内存不能为"written&q