1. 数据结构和系统调用
在Linux下进行C/C++编程,主要通过以下三个系统调用来获取文件(普通文件,目录,管道,socket,字符,块等)属性。
头文件“#include <sys/stat.h>”
(1) //通过文件名称获取文件属性
int stat(const char *restrict pathname, struct stat *restrict buf);
(2) //通过文件描述符获取文件属性
int fstat(int filedes, struct stat *buf);
(3) //通过符号文件名称获取文件属性
int lstat(const char *restrict pathname, struct stat *restrict buf);
返回值(三个函数一样)
成功:0
失败:-1
三个系统调用的区别:
1. fstat接受的第一个参数是“文件描述符”,stat和lstat是“文件全路径”,文件描述符需要用调用open之后才能得到,文件全路经直接写即可;
2. 示例程序
在Linux下进行C/C++编程,主要通过以下三个系统调用来获取文件(普通文件,目录,管道,socket,字符,块等)属性。
头文件“#include <sys/stat.h>”
(1) //通过文件名称获取文件属性
int stat(const char *restrict pathname, struct stat *restrict buf);
(2) //通过文件描述符获取文件属性
int fstat(int filedes, struct stat *buf);
(3) //通过符号文件名称获取文件属性
int lstat(const char *restrict pathname, struct stat *restrict buf);
返回值(三个函数一样)
成功:0
失败:-1
三个系统调用的区别:
1. fstat接受的第一个参数是“文件描述符”,stat和lstat是“文件全路径”,文件描述符需要用调用open之后才能得到,文件全路经直接写即可;
2. lstat获取的是该符号链接本身的信息;而stat获取的是该链接指向的文件的信息;
这三个系统调用都依赖一个重要的结构体struct stat
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; //伟建内容对应的块数量
};
2. 示例程序
(1) 先在测试目录下建立一个test.txt文件,然后"ln -s test.txt link"建立一个符号文件指向test.txt;
(2) 写测试代码
#include <sys/stat.h>
#include <fcntl.h>
#include "stdio.h"
#include "time.h"
#include "unistd.h"
void report(struct stat *ptr)
{
if(!ptr)
{
return;
}
printf("The device no is: %d\n", ptr->st_dev);
printf("The file's node number is: %d\n", ptr->st_ino);
printf("The file's access mode is: %d\n", ptr->st_mode);
printf("The file's hard link number is: %d\n", ptr->st_nlink);
printf("The file's user id is: %d\n", ptr->st_uid);
printf("The file's group id is: %d\n", ptr->st_gid);
printf("The file's size is: %d\n", ptr->st_size);
printf("The block size is: %d\n", ptr->st_blksize);
printf("The number of allocated blocks is: %d\n", ptr->st_blocks);
struct tm* pAccesstime=localtime(&(ptr->st_atime));
struct tm* pModifytime=localtime(&(ptr->st_mtime));
struct tm* pChangetime=localtime(&(ptr->st_ctime));
char aBuffer[64] = {0};
char mBuffer[64] = {0};
char cBuffer[64] = {0};
strftime(aBuffer, 64, "The last access time is: %Y-%m-%d %H:%M:%S \n", pAccesstime);
strftime(mBuffer, 64, "The last modify time is: %Y-%m-%d %H:%M:%S \n", pModifytime);
strftime(cBuffer, 64, "The last change time is: %Y-%m-%d %H:%M:%S \n", pChangetime);
printf(aBuffer);
printf(mBuffer);
printf(cBuffer);
}
void Test(const char* pFileName)
{
if(!pFileName)
{
printf("error: file pointer is null in Test function\n");
return;
}
printf("File %s is be in testing ...\n", pFileName);
struct stat st;
int nRev_st = stat(pFileName, &st);
if(nRev_st < 0)
{
printf("File %s is not existed \n", pFileName);
}
else
{
printf("------get file %s info by stat \n", pFileName);
report(&st);
}
struct stat ls;
int nRev_ls = lstat(pFileName, &ls);
if(nRev_ls < 0)
{
printf("File %s is not existed \n", pFileName);
}
else
{
printf("------get file %s info by lstat \n", pFileName);
report(&ls);
}
struct stat fs;
int fd = open(pFileName, O_RDONLY);
int nRev_fs = fstat(fd, &fs);
close(fd);
if(nRev_fs < 0)
{
printf("File %s is not existed \n", pFileName);
}
else
{
printf("------get file %s info by fstat \n", pFileName);
report(&fs);
}
}
int main()
{
const char* pFileName_Real = "test.txt";
const char* pFileName_Link = "link";
Test(pFileName_Real);
printf("\n\n");
Test(pFileName_Link);
return 0;
}