在我的程序中,我正在显示文件列表。现在我正在使用内置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;}
}
答案 0 :(得分:1)
d_name
只是文件名,而不是文件路径。因此stat
只有在您检查当前工作目录时才会成功。否则,您要么stat
某个其他文件,它恰好与目标目录中的文件同名,或者scan
将返回错误。
检查所有系统调用是否有错误返回是一个非常好的习惯。它可以节省许多小时的调试时间。
此外,即使更正了,该代码最终会在同一个文件上多次调用stat
,这是非常低效的(尽管现代操作系统通常会缓存统计数据,甚至文件路径解析信息,所以它&#39 ;不像过去那样糟糕)。您最好使用readdir
获取未分类的dirents向量,然后为每个文件收集stat
一次,然后根据stat向量对文件向量进行排序。 (或者,您可以保留由inode索引的创建时间的哈希映射,但这样做的工作量更大。)
答案 1 :(得分:0)
找到了有效的实施方案
/* sortbydatetime - helper for scandir sorting */
static inline int
sortbydatetime(const struct dirent **a, const struct dirent **b)
{
int rval;
struct stat sbuf1, sbuf2;
char path1[PATH_MAX], path2[PATH_MAX];
snprintf(path1, PATH_MAX, "%s/%s", PRINT_SPOOLER_PATH, (*a)->d_name);
snprintf(path2, PATH_MAX, "%s/%s", PRINT_SPOOLER_PATH, (*b)->d_name);
rval = stat(path1, &sbuf1);
if (rval) {
perror("stat");
return 0;
}
rval = stat(path2, &sbuf2);
if (rval) {
perror("stat");
return 0;
}
return sbuf1.st_mtime < sbuf2.st_mtime;
}
这是来自
的SPOOL队列代码的一部分https://github.com/vatlidak/cucs-sea-hmwk2/blob/master/src/showqueue.c#L30
答案 2 :(得分:0)
以上答案不正确。
返回sbuf1.st_mtime
如果sbuf1.st_mtime> sbuf2.st_mtime将返回0,并且返回0将导致不确定的订单
应为:
返回sbuf1.st_mtime-sbuf2.st_mtime;