2019年3月11日星期一

借用网上的遍历目录的代码要当心

前段时间写的一段程序需要遍历一个目录下的所有文件,将其中所有的常规文件都上传到FTP服务器上。之前从未写过遍历一个目录下所有文件的程序,因此从网上摘抄了一段代码,实现如下:
while (ptr_dir && ((dir_entry = readdir(ptr_dir)) != NULL))
{
    if(dir_entry->d_type & DT_REG)
    {
        /****/
    }
}
我的开发机用的是Fedora 29. 这段代码在我的开发机上从未出过问题. 生产环境是CentOS 7的虚拟机,当我把程序放到这上面,问题出现了——我加省略号的这段代码根本进不去。开始以为是权限问题,经检查没有问题,百思不得其解。后来在网上搜索才知道,原来竟然是XFS文件系统下,dirent结构体中的d_type成员无法正确获取。于是将这段代码改成如下问题解决。
while (ptr_dir && ((dir_entry = readdir(ptr_dir)) != NULL))
{
   stat(dir_entry->d_name, &statbuf);
   if (statbuf.st_mode & S_IFREG)
   {
       /****/
   }
}
这个问题一方面说明了借用网上的代码一定要当心。网上搜遍历目录的代码,绝大部分人都是前面第一种代码。看似很成熟,实则存在很严重的兼容性问题,换一种文件系统就挂逼了。另一方面说明readdir这个函数写得也很坑。用户调用这个函数,本不应该关注文件系统格式. 文件系统之间的差异,应由函数本身处理,对外提供一致的接口。

没有评论:

发表评论