红联Linux门户
Linux帮助

Linux读取文件属性C接口测试

发布时间:2017-02-13 10:12:40来源:linux网站作者:erlang_hell
在Linux中,需要在C里面调用函数去检查文件状态。Linux中文件是否被修改过,我们可以通过读取文件属性,或者通过md5sum来检查文件是否被修改过。
 
这个代码是man 3 stat中的实例代码:
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
#include <locale.h>
#include <langinfo.h>
#include <stdio.h>
#include <stdint.h>
struct dirent  *dp;
struct stat     statbuf;
struct passwd  *pwd;
struct group   *grp;
struct tm      *tm;
char            datestring[256];
/* Loop through directory entries. */
while ((dp = readdir(dir)) != NULL) {
/* Get entry's information. */
if (stat(dp->d_name, &statbuf) == -1)
continue;
/* Print out type, permissions, and number of links. */
printf("%10.10s", sperm (statbuf.st_mode));
printf("%4d", statbuf.st_nlink);
/* Print out owner's name if it is found using getpwuid(). */
if ((pwd = getpwuid(statbuf.st_uid)) != NULL)
printf(" %-8.8s", pwd->pw_name);
else
printf(" %-8d", statbuf.st_uid);
/* Print out group name if it is found using getgrgid(). */
if ((grp = getgrgid(statbuf.st_gid)) != NULL)
printf(" %-8.8s", grp->gr_name);
else
printf(" %-8d", statbuf.st_gid);
/* Print size of file. */
printf(" %9jd", (intmax_t)statbuf.st_size);
tm = localtime(&statbuf.st_mtime);
/* Get localized date string. */
strftime(datestring, sizeof(datestring), nl_langinfo(D_T_FMT), tm);
printf(" %s %s\n", datestring, dp->d_name);
}
 
阅读这个代码基本上能知道如何通过path将这个文件的属性抓取出来。关于文件信息(struct stat)的定义。
struct stat  
{  
dev_t       st_dev;     /* ID of device containing file -文件所在设备的ID*/    
ino_t       st_ino;     /* inode number -inode节点号*/    
mode_t      st_mode;    /* protection -保护模式?*/    
nlink_t     st_nlink;   /* number of hard links -链向此文件的连接数(硬连接)*/    
uid_t       st_uid;     /* user ID of owner -user id*/    
gid_t       st_gid;     /* group ID of owner - group id*/    
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 blocks allocated -文件所占块数*/    
time_t      st_atime;   /* time of last access -最近存取时间*/    
time_t      st_mtime;   /* time of last modification -最近修改时间*/    
time_t      st_ctime;   /* time of last status change - 文件状态改变时间 */    
};  
 
如果是想检查文件是否被修改了,可以查看st_mtime这个时间戳是否有更改。是不是很简单。
在stat的返回值提到的信息:
Upon successful completion, 0 shall be returned. Otherwise, -1 shall be returned and errno set to indicate the error.
 
获取成功之后将会得到0,否则将会返回-1值,而且可以通过errno获取所指的具体错误。具体可能出现的问题有:
ERRORS
The stat() function shall fail if:
EACCES Search permission is denied for a component of the path prefix.
EIO    An error occurred while reading from the file system.
ELOOP  A loop exists in symbolic links encountered during resolution of the path argument.
ENAMETOOLONG
The length of the path argument exceeds {PATH_MAX} or a pathname component is longer than {NAME_MAX}.
ENOENT A component of path does not name an existing file or path is an empty string.
ENOTDIR
A component of the path prefix is not a directory.
EOVERFLOW
The file size in bytes or the number of blocks allocated to the file or the file serial number cannot be represented correctly in the structure pointed to by buf.
The stat() function may fail if:
ELOOP  More than {SYMLOOP_MAX} symbolic links were encountered during resolution of the path argument.
ENAMETOOLONG
As a result of encountering a symbolic link in resolution of the path argument, the length of the substituted pathname string exceeded {PATH_MAX}.
EOVERFLOW
A value to be stored would overflow one of the members of the stat structure.
The following sections are informative.
 
有一个重要的原则是,每个函数的返回值,其实都需要做关注。否则当出现的问题的时候,回头找中间的原因将会是一件很困难的事情。
#include <string.h>
char *strerror(int errnum);
int dfd = open(argv[i], O_RDONLY);
if (dfd == -1)
{
fprintf(stderr, "Failed to open directory %s for reading (%d: %s)\n",
argv[i], errno, strerror(errno));
continue;
}
 
这种写法将会有利于今后检查错误。通常狡猾的bug如同平时家里藏污纳垢之处,没有将事情明白交代清楚,最终都会害了自己。
 
接下来介绍通过md5sum来检查文件内容是否存在差异。这个就需要借助openssl库来将文件的全部的内存都读取出来,并且来计算即可。
 
本文永久更新地址:http://www.linuxdiyf.com/linux/28370.html