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. lstat获取的是该符号链接本身的信息;而stat获取的是该链接指向的文件的信息;
这三个系统调用都依赖一个重要的结构体struct stat
- struct stat {
- mode_t st_mode;
- ino_t st_ino;
- 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;
- }
(3) 运行结果