通常我们在获取文件大小的时候都是用使用C语言的fseek和ftell组合来获取,fsekk将fd设置到文件尾SEEK_END,然后使用ftell的返回值获取大小。
这种做法很常见,但如果遇到大文件就会有问题,比如超过2G的文件。因为ftell返回的是long,在不同的系统环境下长度能支持的最大字节数不同。
其实ANSI C里面还是提供了另外一个接口获取文件属性
fstate
通过man 2 fstate 命令我们可以看到
NAME
stat, fstat, lstat - get file status
SYNOPSIS
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *path, struct stat *buf);
int fstat(int fd, struct stat *buf);
int lstat(const char *path, struct stat *buf);
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
lstat(): _BSD_SOURCE || _XOPEN_SOURCE >= 500
三个函数基本上一样,区别在于fstat使用的入参是fd,lstat是软链文件。
再看下返回struct stat :
struct stat {
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* inode number */
mode_t st_mode; /* protection */
nlink_t st_nlink; /* number of hard links */
uid_t st_uid; /* user ID of owner */
gid_t st_gid; /* group ID of owner */
dev_t st_rdev; /* device ID (if special file) */
off_t st_size; /* total size, in bytes */
blksize_t st_blksize; /* blocksize for file system I/O */
blkcnt_t st_blocks; /* number of 512B 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_size 就是我们需要的文件大小,其它几个属性也很常用。后面的几个时间也经常会用在文件监控。
下面我们写个小程序测试一下:
#include <sys/stat.h>
int getFileSize(const char* dstFileName)
{
struct stat statbuf;
stat(dstFileName,&statbuf);
int size=statbuf.st_size;
return size;
}
int main(int argc ,char* argv[])
{
printf("%d", getFileSize(argv[1])) ;
return 0 ;
}
编译运行:
g++ filesize.cpp
./a.out /tmp/checkmysql.log
19533
Done~~




