读取文件元数据、
应用程序能够通过调用 stat 和 fstat 函数,检索到关于文件的信息(有时也称为文件的元数据(metadata))。
函数说明 fstat()用来将参数fd所指的文件状态,复制到参数buf所指的结构中(struct stat)。fstat()与stat()作用完全相同,不同处在于传入的参数为已打开的文件描述词。两个函数成功返回0,失败返回-1,并且设置error的值
//参数不同,一个是文件路径,一个是以打开的文件描述符
int stat(const char *path, struct stat *buf);
int fstat(int fd,struct stat *buf);
typedef struct stat
{
dev_t st_dev; //文件的设备编号
ino_t st_ino; //节点
mode_t st_mode; //文件的类型和存取的权限
nlink_t st_nlink; //连到该文件的硬连接数目,刚建立的文件值为1
uid_t st_uid; //用户ID
gid_t st_gid; //组ID
dev_t st_rdev; //(设备类型)若此文件为设备文件,则为其设备编号
off_t st_size; //文件字节数(文件大小)
unsigned long st_blksize; //块大小(文件系统的I/O 缓冲区大小)
unsigned long st_blocks; //块数
time_t st_atime; //最后一次访问时间
time_t st_mtime; //指最近修改文件内容的时间
time_t st_ctime; //指最近改动Inoed的时间
}stat;
#include<iostream>
using namespace std;
#include<mutex>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<cstring>
#include<dirent.h>
//安全的输出函数
mutex print_mutex{};
template<class...Args>
void print(const Args&...args)
{
lock_guard<mutex> m(print_mutex);
((cout << args),...);
}
//输出错误函数
void unix_error(const char* msg)
{
print(msg);
exit(0);
}
//安全考虑的open函数,第一个参数是文件路径,第二个参数是打开的模式
int Open(const char* path,int flag)
{
int fd = 0;
//打开文件失败会返回-1
if((fd = open(path,flag)) < 0)
{
unix_error("open file error\n");
}
return fd;
}
//安全考虑的close函数,参数是文件描述符
void Close(int fd)
{
int res = 0;
if((res = close(fd)) < 0)
{
unix_error("close file error\n");
}
}
//安全考虑的read函数
void Read(int fd,char*buf,size_t len)
{
size_t left = len;
size_t reads = 0;
char* tmp = buf;
while(left > 0)
{
//error
if((reads = read(fd,buf,left)) < 0)
{
unix_error("read file error\n");
}
//EOF
else if(reads == 0)
{
break;
}
left -= reads;
tmp += reads;
}
}
//安全考虑的write函数
void Write(int fd,char*buf,size_t len)
{
int n = 0;
if((n = write(fd,buf,len)) < 0)
{
unix_error("write file error\n");
}
}
//读取文件元数据
void read_file_data(const char* path)
{
struct stat status;
if(stat(path,&status) < 0)
{
unix_error("read file data error\n");
}
print("filename : ",path,"\n");
//S_ISDIR是一个宏函数,判断st_mode是不是目录,是返回1,不是返回0
print("type : ",(S_ISDIR(status.st_mode) == 1 ? "dir" : "regular file"),"\n");
print("size : ",status.st_size,"\n");
print("user : ",status.st_uid,"\n");
}
int main(int args,char* argv[],char* envp[])
{
if(argv[1])
{
read_file_data(argv[1]);
}
return 0;
}
st_mode 详细内容文章 Linux:st_mode详细分析_Echo_Xiaozhi的博客
打开,读取目录的内容、
opendir()用来打开参数指定的目录, 并返回DIR*形态的目录流, 和open()类似, 接下来对目录的读取和搜索都要使用此返回值。 成功则返回DIR* 型态的目录流, 打开失败则返回NULL。
DIR类似于文件描述符,是一个描述目录的东西,不太重要,故不去深入研究。
DIR * opendir(const char * name);
应用程序可以用 readdir 系列函数来读取目录的内容。成功返回dirent的指针,失败返回NULL。
readdir每一次只会按顺序读取目录下的一个文件,需要在循环内才能够读取到目录下的所有文件!!!
struct dirent* readdir(DIR* dir_handle);
struct dirent
{
ino_t d_ino; //d_ino 此目录进入点的inode
ff_t d_off; //d_off 目录文件开头至此目录进入点的位移
signed short int d_reclen; //d_reclen _name 的长度, 不包含NULL 字符
unsigned char d_type; //d_type d_name 所指的文件类型
har d_name[256]; //d_name 文件名
};
d_type 的类型如下:
DT_REG 常规文件
DT_DIR 目录
DT_SOCK 套接字
DT_LNK 符号链接
DT_CHR 字符设备
DT_FIFO 一个命名管道,或FIFO。
函数 closedir 关闭流并释放其所有的资源,成功返回0,失败返回-1。
closedir(DIR* dir);
chdir() 是linux中的一个系统调用函数(同cd),用于改变当前工作目录,其参数为Path 目标目录,可以是绝对目录或相对目录。成功返回0,失败返回-1。
int chdir(const char *path);
下面的程序打印一个目录下所有的文件!!!
#include<iostream>
using namespace std;
#include<mutex>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<cstring>
#include<dirent.h>
//安全的输出函数
mutex print_mutex{};
template<class...Args>
void print(const Args&...args)
{
lock_guard<mutex> m(print_mutex);
((cout << args),...);
}
//输出错误函数
void unix_error(const char* msg)
{
print(msg);
exit(0);
}
//打印path下的所有文件名称,递归实现
void print_dir(const char* path)
{
//首先打开path目录
DIR* dir = opendir(path);
if(dir == nullptr) //打开失败就返回,这也是递归出口
{
return;
}
//保存目录下文件信息所需要的结构体指针
struct dirent*status = nullptr;
//改变工作目录,很重要!!!
if(chdir(path) < 0)
{
unix_error("change dir error\n");
}
//循环读取目录下的每一个文件
while(status = readdir(dir))
{
//读取目录下文件时会读取到 . 和 .. 这两个需要忽略掉
if(strcmp(status->d_name,".") != 0 && strcmp(status->d_name,"..") != 0)
{
//分类讨论读取到的文件类型
switch(status->d_type)
{
//目录的情况
case DT_DIR:
print("dir : ",status->d_name,"\n");
print_dir(status->d_name);
//改变工作目录,很重要!!!
if(chdir(path) < 0)
{
unix_error("change dir error\n");
}
break;
//普通文件的情况
case DT_REG:
print("file : ",status->d_name,"\n");
break;
default:
break;
}
}
if(closedir(dir) < 0)
{
unix_error("close dir error\n");
}
}
int main()
{
char path[30];
cin >> path;
print_dir(path);
return 0;
}
Comments NOTHING