本文主要是介绍(P6)文件与IO:stat、stat结构体,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
文章目录
- 1.stat
- 2.stat结构体
- 3.stat的eg
- 4.实现ls -l功能需要的函数
1.stat
- 功能:读取文件元数据
int stat(const char *pathname, struct stat *buf);
int fstat(int fd, struct stat *buf);
int lstat(const char *pathname, struct stat *buf);
- lstat与stat的区别:
若是符号链接文件,lstat查看的是符号链接本身的状态,而stat查看的是符号链接所指向的文件的状态
2.stat结构体
struct stat {dev_t st_dev; /* ID of device containing file */设备号:高8位放主设备号,低8位放次设备号ino_t st_ino; /* inode number */mode_t st_mode; /* file type and mode */文件权限,文件类型nlink_t st_nlink; /* number of hard links */uid_t st_uid; /* user ID of owner */gid_t st_gid; /* group ID of owner */dev_t st_rdev; /* device ID (if special file) */若是设备文件,设备文件所所对应的设备号off_t st_size; /* total size, in bytes */blksize_t st_blksize; /* blocksize for filesystem I/O */blkcnt_t st_blocks; /* number of 512B blocks allocated */若是块设备文件,块设备的数量/* Since Linux 2.6, the kernel supports nanosecondprecision for the following timestamp fields.For the details before Linux 2.6, see NOTES. */struct timespec st_atim; /* time of last access */struct timespec st_mtim; /* time of last modification */struct timespec st_ctim; /* time of last status change */#define st_atime st_atim.tv_sec /* Backward compatibility */#define st_mtime st_mtim.tv_sec#define st_ctime st_ctim.tv_sec};
3.stat的eg
- eg:代码:
//下面的头文件来自man 2 open
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>//下面的头文件来自man 2 stat
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>//获取高8位
#define MAJOR(a) (int)((unsigned short)a >> 8)
//获取低8位
#define MAJOR(a) (int)((unsigned short)a & 0xFF)#define ERR_EXIT(m) \do \{ \perror(m); \exit(EXIT_FAILURE); \} while(0)int filetype(struct stat *buf);
void filepermission(struct stat *buf, char *perm);int main(int argc, char **argv)
{if (argc != 2)fprintf(stderr, "Usage %s file\n", argv[0]);struct stat sbuf;printf("filename:%s\n", argv[1]);if (stat(argv[1], &sbuf) == -1)ERR_EXIT("stat error");printf("File number:major %d, minnor %d, inode %d\n", MAJOR(sbuf.st_dev), MINOR(sbuf.st_dev), (int)sbuf.st_ino);if(filetype(&sbuf))printf("Device number:major %d, minor %d\n", MAJOR(sbuf.st_dev), MINOR(sbuf.st_dev));//输出文件权限,注意要与上0777//%o输出8进制数printf("FIle permission bits=%o\n", sbuf.st_mode & 0777);char perm[11] = '0';filepermission(&sbuf, perm)printf("FIle permission bits=%o_%s\n", sbuf.st_mode & 0777, perm);return 0;
}int filetype(struct stat *buf)
{//文件类型在man 2 statint flag = 0;printf("filetype");mode_t mode;mode = buf->st_mode;switch (mode & S_IFMT){case S_IFSOCK:printf("socket\n");break;case S_IFLNK:printf("symbolic link\n");break;case S_IFREG:printf("regular file\n");break;case S_IFBLK:printf("block device\n");flag =1;break;case S_IFDIR:printf("directory\n");break;case S_IFCHR:printf("character device\n");flag = 1;break; case S_IFIFO:printf("FIFO\n");break; default:printf("unknow file type\n");break; }return flag;
}//将文件权限转换成字符
void filepermission(struct stat *buf, char *perm)
{//初始化strcpy(perm, "----------");perm[0]="?";mode = buf->st_mode;switch (mode & S_IFMT){case S_IFSOCK:perm[0] = 's';break;case S_IFLNK:perm[0] = 'l';break;case S_IFREG:perm[0] = '-';break;case S_IFBLK:perm[0] = 'b';flag =1;break;case S_IFDIR:perm[0] = 'd';break;case S_IFCHR:perm[0] = 'c';flag = 1;break; case S_IFIFO:perm[0] = 'p';break; }if (mode & S_IRUSR)perm[1] = 'r';if (mode & S_IWUSR)perm[2] = 'w';if (mode & S_IXUSR)perm[3] = 'x';if (mode & S_IRGRP)perm[4] = 'r';if (mode & S_IXGRP)perm[5] = 'w';if (mode & S_IXGRP)perm[6] = 'x';if (mode & S_IROTH)perm[7] = 'r';if (mode & S_IXOTH)perm[8] = 'w';if (mode & S_IXOTH)perm[9] = 'x';perm[10] = '\0';
}
-
测试:
为什么Makefile的主设备号是8,次设备号是1,因为Makefile是在sda1分区上,sda1分区又属于sda硬盘
主设备号用来区分不同的设备,次设备号用来区分同一设备中不同小类别,比如磁盘中不同的分区,sda1分区1,sda2分区2,sda硬盘的主设备号是8。
主设备号解决了什么的驱动程序访问设备
通过ls -l /dev/tty2可以看到他的主设备号是4,次设备号是2
Makefile文件的inode号
普通文件和字符设备文件打印(终端是字符设备文件)
Makefile的权限是644
-
Makefile
.PHONY:clean all
CC=gcc
CFLAGS=-Wall -g
BIN=01stat
all:$(BIN)
%.o:%.c$(CC) $(CFLAGS) -c $< -o $@
clean:rm -f *.o $(BIN)
4.实现ls -l功能需要的函数
- lstat
- getpwuid
获取uid - getgrgid
获取组id - readlink
man 2 readlinkssize_t readlink(const char *path, char *buf, size_t bufsiz);
由path获取其所指向的文件,保存在buf里
这篇关于(P6)文件与IO:stat、stat结构体的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!