c - 按创建时间排序 scandir()

标签 c posix

在我的程序中,我显示了一个文件列表。现在我正在使用带有内置 alphasort 函数的 scandir,但是我想根据创建日期进行排序。我写了自己的比较函数,但无论我测试多少,它都不起作用。这些项目以看似随机的顺序出现。有些可能是有序的,但最旧的文件可能会出现在中间。例如,假设我有以下来自 ls 的输出

Nov  9 22:39 file1
Nov  9 19:40 file2
Nov  9 19:39 file3
Nov  9 19:09 file4

然后我得到类似的输出,既不是升序也不是降序。

file2
file1
file3
file4

我已经尝试了 st_mtime 和 st_ctime,因为我知道有时创建日期不可用。如果我查看“ls -lt”的输出,那么我会看到所有文件,时间正确,按正确顺序排序 - 所以我知道这些文件包含我需要的信息。

int datesort(const struct dirent** file1, const struct dirent** file2) {
    struct stat info1, info2;
    stat((*file1)->d_name, &info1);
    stat((*file2)->d_name, &info2);

    double diff = difftime(info1.st_ctime, info2.st_ctime);
    if (diff<0) {return -1;}
    if (diff>0) {return 1;}
    if (diff==0) {return 0;}
}

最佳答案

d_name 只是文件名,不是文件路径。所以 stat 只有在检查当前工作目录时才会成功。否则,您将 stat 一些其他文件,巧合的是与目标目录中的文件同名,或者 scan 将返回错误。

检查所有系统调用的错误返回是一个非常好的习惯。它可以节省许多小时的调试时间。

此外,即使得到纠正,该代码最终也会对同一个文件多次调用 stat,这是非常低效的(尽管现代操作系统通常缓存统计数据,甚至文件路径解析信息,所以它不像以前那么糟糕)。您最好使用 readdir 获取未排序的目录 vector ,然后为每个文件收集一次 stat,然后根据统计 vector 对文件 vector 进行排序. (或者,您可以保留一个由 inode 索引的创建时间的散列图,但这需要更多的工作。)

关于c - 按创建时间排序 scandir(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26838044/

相关文章:

以原子方式创建文件

c++ - 如何在不继承句柄的情况下 fork 进程?

c - 使用一个进程向多个其他进程发送信号 "simultaneously"

c - 在其 makefile 中引用 C 代码定义的宏

c++ - 如何抑制::system ("del *.log"的输出)出现在控制台中

c++ - "usual arithmetic conversions"和 "integer promotions"是一回事吗?

unix - 如果我将accept(3)应用于IPv4套接字,我可以假设它返回IPv4地址吗?

c - 将制表符分隔的数据读取到 C 中的数组

c++ - C和C++中静态变量初始化的区别

检查文件是否在C中的目录中