Linux学习笔记2——stat与获取文件类型

1,stuct stat

一个文件的常用信息,包括:权限、文件类型、文件所有者、文件大小、文件改动时间等信息都存储在一个结构体中,即struct stat。
这个结构体定义在stat.h头文件中。
基本形式如下:
struct stat {
	mode_t st_mode; //文件对应的模式,文件,目录等
	ino_t st_ino; //inode节点号
	dev_t st_dev; //设备号码
	dev_t st_rdev; //特殊设备号码
	nlink_t st_nlink; //文件的连接数
	uid_t st_uid; //文件所有者
	gid_t st_gid; //文件所有者对应的组
	off_t st_size; //普通文件,对应的文件字节数
	time_t st_atime; //文件最后被访问的时间
	time_t st_mtime; //文件内容最后被修改的时间
	time_t st_ctime; //文件状态改变时间
	blksize_t st_blksize; //文件内容对应的块大小
	blkcnt_t st_blocks; //伟建内容对应的块数量
};


系统中的具体实现可能与之略有出入。比如我的电脑上,其实际的实现为:
struct stat {
	unsigned long	st_dev;		/* Device.  */
	unsigned long	st_ino;		/* File serial number.  */
	unsigned int	st_mode;	/* File mode.  */
	unsigned int	st_nlink;	/* Link count.  */
	unsigned int	st_uid;		/* User ID of the file's owner.  */
	unsigned int	st_gid;		/* Group ID of the file's group. */
	unsigned long	st_rdev;	/* Device number, if device.  */
	unsigned long	__pad1;
	long		st_size;	/* Size of file, in bytes.  */
	int		st_blksize;	/* Optimal block size for I/O.  */
	int		__pad2;
	long		st_blocks;	/* Number 512-byte blocks allocated. */
	long		st_atime;	/* Time of last access.  */
	unsigned long	st_atime_nsec;
	long		st_mtime;	/* Time of last modification.  */
	unsigned long	st_mtime_nsec;
	long		st_ctime;	/* Time of last status change.  */
	unsigned long	st_ctime_nsec;
	unsigned int	__unused4;
	unsigned int	__unused5;
};

2,获取该结构体

#include<sys/stat.h>
int stat(const char *path, struct stat *struct_stat);

int fstat(int fd, struct stat *buf);

int lstat(const char *path,struct stat *struct_stat);

int fstat(int fdp, struct stat *struct_stat);  //通过文件描述符获取文件对应的属性。fdp为文件描述符

这4个函数可用于获取该结构体。stat和lstat的区别在于对符号链接的处理。lstat返回该符号链接的有关信息,而不是该符号链接所引用的文件的信息。

以上4个函数,执行成功时返回0,执行失败时返回-1.
具体的使用方法如下:
if((lstat(path, &file_info)) < 0)
{
	printf("lstat error!\n");
	continue;
}

3,文件类型

Linux上常用的文件类型包括:
  • 普通文件
  • 目录文件
  • 块特殊文件(提供对设备带缓冲的访问)
  • 字符特殊文件(提供对设备不带缓冲的访问)
  • FIFO(用于进程间通信,又称为管道)
  • 套接字(用于进程间网络通信)
  • 符号链接
文件的类型信息可以从stat结构体的st_mode成员中获取。st_mode成员一般是一个32位的整型,其13到16这4位代表的是文件类型信息。
可用现成的宏定义判断文件类型:
S_ISREG()      普通文件
S_ISDIR()      目录文件
S_ISCHR()      字符特殊文件
S_ISBLK()      块特殊文件
S_ISFIFO()     管道
S_ISLNK()      符号链接
S_ISSOCK()     套接字

其在头文件中的具体实现如下:
#define S_ISLNK(m)	(((m) & S_IFMT) == S_IFLNK)
#define S_ISREG(m)	(((m) & S_IFMT) == S_IFREG)
#define S_ISDIR(m)	(((m) & S_IFMT) == S_IFDIR)
#define S_ISCHR(m)	(((m) & S_IFMT) == S_IFCHR)
#define S_ISBLK(m)	(((m) & S_IFMT) == S_IFBLK)
#define S_ISFIFO(m)	(((m) & S_IFMT) == S_IFIFO)
#define S_ISSOCK(m)	(((m) & S_IFMT) == S_IFSOCK)

IMFT即为 0XF000,13到16位全1
具体的使用方法如下:
if (S_ISREG(file_info.st_mode))
	ptr = "regular";//普通文件

4,示例

int main(int argc, char* argv[])
{
	// 4.3 lstat 通过st_mode获取文件类型
	int i = 0; //输入的文件名编号
	struct stat file_info;
	char *ptr;

	printf("S_IFMT = %d, S_IFREG = %d\n", S_IFMT, S_IFREG);
	
	printf("argc = %d\n", argc);
	for (i = 1; i < argc; i++)
	{
		printf("%s: ",argv[i]);
		if((lstat(argv[i], &file_info)) < 0)
		{
			printf("lstat error!\n");
			continue;
		}

		printf("st_mtime = %ld\n",file_info.st_mtime );
		
		if (S_ISREG(file_info.st_mode))
			ptr = "regular";//普通文件
		else if(S_ISDIR(file_info.st_mode))
			ptr = "direction";//目录文件
		else if(S_ISCHR(file_info.st_mode))
			ptr = "character special";//字符特殊文件
		else if(S_ISBLK(file_info.st_mode))
			ptr = "block special"; //块特殊文件
		else if(S_ISFIFO(file_info.st_mode))
			ptr = "FIFO";
		else if(S_ISLNK(file_info.st_mode))
			ptr = "link";
		else if(S_ISSOCK(file_info.st_mode))
			ptr = "sock";
		else
			ptr = "unknown mode";
		printf("%s file\n", ptr);
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值