2017-08-04 101 views
1

我正在写一个实用程序来递归扫描目录树并记录文件名和大小的树结构。 (尽可能快)如何获得给定名称和父目录句柄或inode的文件大小?

也许我已经把自己编码到了一个角落。我可以用readdir(3)获取目录的内容,并分别处理常规文件和目录。

我看不到如何获得除openat(), fstat(), close()调用以外的常规文件的文件大小。

有没有办法在我处理目录条目时更直接地获取文件大小?也许从inode号码?

我期待这会存在:statat(int parentDirFD, const char * filename)因为我只有文件名,而不是文件路径。

我的内核似乎没有O_PATH支持。

#include <sys/types.h> 
#include <sys/stat.h> 
#include <dirent.h> 

DIR* p_dir = ...; 

int dir_fd = dirfd(p_dir); 


size_t get_file_size(const char * filename_only, int dir_fd, DIR* pdir) 
{ 
    //// this just strikes me as overly expensive: 
    int fd = openat(dir_fd, filename_only, O_RDONLY); 
    struct stat sb; 
    fstat(fd, &sb); 
    size_t file_size = sb.st_size; 
    close(fd); 
    ////// 

    return file_size; 
} 
+3

,你希望被调用的函数'statat'实际上是所谓的'fstatat'。它需要一个额外的标志参数来确定它是否在符号链接的情况下具有类似lstat的行为。 [POSIX spec](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fstatat.html)[Linux man page](http://man7.org/linux/man-pages/man2/fstatat.2 .html) –

+0

哦,我的天哪。它是!我想我在查看我的goto web手册页[fstat](https://linux.die.net/man/2/fstat)时忽略了它。 – NoahR

回答

0

有一次,Wumpus Q. Wumbley在评论中给出了答案,结果证明这很容易。 fstatat()

#include <sys/types.h> 
#include <sys/stat.h> 
#include <dirent.h> 

DIR* p_dir = ...; 

int dir_fd = dirfd(p_dir); 


size_t get_file_size(const char * filename_only, int dir_fd) 
{ 
    struct stat sb; 
    int fstatat_flags = 0; //| AT_SYMLINK_NOFOLLOW 
    int stat_res = fstatat(dir_fd, filename_only, &sb, fstatat_flags); 
    size_t file_size = sb.st_size; 

    return file_size; 
} 
+0

出于好奇,你有没有发现你的系统在'fstatat'(和'openat' +'fdopendir'我猜想)和传递完整路径名之间有任何性能差异?几年前,我做了一些修补工作,希望能够削减一些周期,并回想起结果有些不知所措。 – doynax

相关问题