这篇将从stat结构开始,逐个说明stat结构的每个成员以了解文件的所有属性。
1.stat,fstat和lstat函数——获取文件结构信息
2.文件类型#include <sys/types.h> #include <sys/stat.h> int stat(const char *pathname,struct stat *buf); int fstat(int filedes,struct stat *buf); int lstat(const char *pathname,struct stat *buf);
给定pathname,stat返回一个与此命名文件有关的信息结构,fstat函数获得已经打开文件描述符filedes指定的文件的信息。lstat和stat类似,不过lstat不跟踪符号连接,即不解析符号连接所引用的文件,而是引用符该号连接本身的文件。
struct stat结构可能与实现不同而不同,但其基本形式是:
struct stat{ mode_t st_mode; //file type & mode (permission) ino_t st_ino; //i-node number (serial) number dev_t st_dev; //device number file system dev_t st_rdev; //device number for special files nlink_t st_nlink; //number of links uid_t st_uid; //user ID of owner gid_t st_gid; //group ID of owner off_t st_size; //size in bytes,for regular files time_t st_atime; //time of last access time_t st_mtime; //time of last modification time_t st_ctime; //time of last file status change long st_blksize; //best I/O block size long st_blocks; //number of 512-byte blocks number };
UNIX支持的文件类型,主要是:
(1)普通文件(regular file)这是最常见的文件类型,这种文件包含了某种形式的数据,至于是二进制还是文本的形式对于内核来说并无区别,对于普通文件内容的解释由处理此文件的应用程序进行。
(2)目录文件(directory file)这种文件包含了其他文件的名字以及指向这些名字有关文件的指针信息。对于一个目录文件具有读许可权的任一进程都可以读该目录的内容,但只有内核可以写目录文件。
(3)字符特殊文件(character special file)用于系统中某些类型的设备,最典型就是终端。
(4)块特殊文件(block special file)典型地用于磁盘设备
(5)FIFO:这中文件用于进程间通信,也称为命名管道
(6)套接字(socket)这种文件用于进程间网络通信
(7)符号连接(symbol link)这种文件指向另一个文件。
文件信息包含子stat结构的st_mode成员中,可以用如下宏来测试
实例:S_ISREG() 普通文件 S_ISDIR() 目录文件 S_ISBLK() 块特殊文件 S_ISCHR() 字符特殊文件 S_ISFIFO() 命名管道 S_ISLNK() 符号连接 S_ISSOCK() 套接字
取命令行参数,然后针对每一个命令行参数打印其文件类型
#include <errno.h> #include <sys/types.h> #include <sys/stat.h> #include <stdio.h> int main(int argc,char *argv[]){ int i; struct stat buf; for(i=1;i<argc;i++){ printf("%s ",argv[i]); if( lstat(argv[i],&buf) <0){ perror("lstat error"); return -1; } if( S_ISREG(buf.st_mode)) printf("regular"); else if(S_ISDIR(buf.st_mode)) printf("direcotry"); else if(S_ISFIFO(buf.st_mode)) printf("FIFO"); else if(S_ISBLK(buf.st_mode)) printf("block special file"); else if(S_ISCHR(buf.st_mode)) printf("charcter special file"); #ifdef S_ISLNK else if( S_ISLNK(buf.st_mode)) printf("symbol link"); #endif #ifdef S_ISSOCK else if( S_ISSOCK(buf.st_mode)) printf("socket"); #endif else{ perror("**Unknown mode **"); return -1; } puts("\n"); } return 0; }
早期的UNIX版本不提供S_ISxxx宏,于是就需要将st_mode与屏蔽字S_IFMT逻辑与,然后与名为S_IFxxx常数比较,来确定文件类型
#define S_ISDIR(mode) (((mode)&S_IFMT)==S_IFDIR)
普通文件是所有文件类型中占比例最大的文件类型。
本来想把所有的写成一篇文章,但是一看,内容太多了,而且今天写不完,所以更名为《UNIX文件属性(1)》,今天就先写到这儿吧,时间不早了,明天开始去学车——场地,好几天没摸了,有点手痒。