在Unix/Linux系统编程中,stat()和fstat()是两个基础但至关重要的系统调用。它们就像文件系统的"体检医生",能够让我们获取文件的各种元数据信息。我经常在性能调优、文件监控等场景中使用它们,今天就来详细拆解这两个函数的原理和使用技巧。
stat()通过文件路径获取信息,其函数原型为:
c复制int stat(const char *pathname, struct stat *statbuf);
典型使用场景包括:
注意:使用stat()前务必检查路径权限,否则可能遇到EACCES错误。
fstat()则通过文件描述符工作:
c复制int fstat(int fd, struct stat *statbuf);
它与stat()的主要区别在于:
struct stat结构体包含约20个字段,其中最重要的包括:
| 字段名 | 类型 | 描述 | 示例值 |
|---|---|---|---|
| st_mode | mode_t | 文件类型和权限 | 0644 |
| st_size | off_t | 文件大小(字节) | 1024 |
| st_mtime | time_t | 最后修改时间戳 | 1654567890 |
| st_ino | ino_t | inode编号 | 123456 |
我曾在日志监控系统中这样使用:
c复制struct stat prev, curr;
stat("/var/log/app.log", &prev);
while(1) {
stat("/var/log/app.log", &curr);
if(curr.st_mtime != prev.st_mtime) {
// 触发日志处理逻辑
prev = curr;
}
sleep(1);
}
为防止TOCTOU攻击,最佳实践是:
经过多次性能测试发现:
可能原因:
不同系统的struct stat可能有差异:
使用S_IS*宏系列:
c复制if(S_ISREG(statbuf.st_mode)) {
// 普通文件
} else if(S_ISDIR(statbuf.st_mode)) {
// 目录
}
将time_t转换为可读格式:
c复制char timestr[20];
strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S",
localtime(&statbuf.st_mtime));
在实际项目中,我发现合理使用这些函数可以避免很多文件操作的问题。特别是在处理大容量文件时,提前检查st_size可以防止内存溢出。对于关键业务系统,建议总是添加错误处理逻辑,并考虑使用lstat()来避免符号链接带来的意外情况。