获取目录列表按Dlang中的修改日期排序

时间:2013-03-06 17:17:48

标签: date sorting directory d

我正在尝试获取目录的内容,按修改时间排序。我不认为有一种方法可以在dirEntries调用中直接执行此操作,因此我的策略是收集所有文件时间和名称,然后按锁定步骤对两个数组进行排序。

问题1:我无法弄清楚如何将sysTime转换为整数 问题2:我无法弄清楚如何并行排序两个数组。

与D中的每个问题一样,不可能找到如何做到这一点:(

这是我的代码:

import std.file;
import std.stdio : writeln;
import std.algorithm;
import std.datetime;

void main() {
    string[] myFiles;
    double[] myTimes;

    foreach (DirEntry e; dirEntries("c:/users/istaffel/", SpanMode.shallow)) {
        // calculate unix time (this doesn't work)
        auto dur = (cast(Date)e.timeLastModified) - Date(1970,1,1);

        // store modified time and filename
        myTimes ~= dur.seconds;
        myFiles ~= e.name;
    }

    // now find a way to sort myFiles in order of ascending myTimes...

    // print in order
    for (int i = 0; i < myTimes.length; i++) {
        writeln(myTimes[i], " ", myFiles[i]);
    }
}

1 个答案:

答案 0 :(得分:8)

一般情况下,除非您与C进行交互,否则我建议将SysTime转换为整数值是一个坏主意(并将其转换为double更糟糕)。但是,如果您确实需要将其转换为time_t,就像您似乎正在做的那样,那么只需使用SysTime的{​​{1}}函数:

toUnixTime

做你想做的最简单的解决方案就像是

auto timeT = e.timeLastModified.toUnixTime();

如果您真的想要import std.algorithm; import std.array; import std.datetime; import std.file; import std.stdio; void main(string[] args) { auto directoryToList = args[1]; auto files = array(dirEntries(directoryToList, SpanMode.shallow)); sort!"a.timeLastModified < b.timeLastModified"(files); foreach(file; files) writefln("%s %s", file.timeLastModified, file.name); } ,请将其设为time_t

file.timeLastModified.toUnixTime()返回一个范围,因此您可以直接迭代它并对其进行操作,但为了对其进行排序,您需要一个随机访问范围(dirEntries的结果是'n' t,因为它懒惰地访问文件)。因此,您可以使用dirEntries从中创建一个数组,然后对其进行排序。 std.array.array接受一个谓词(可以是一个转换为带有std.functional的函数的字符串,一个lambda文字,一个委托,一个函数指针,或者用你要排序的类型的两个参数调用的任何东西 - 在这里case我使用了一个字符串,在下面的例子中,我使用lambda文字作为sort)。

如果你正在处理大量文件并希望最小化使用的内存量(因为map确实有几个成员变量,所以它们的数组都可能占用比你更多的内存如果您关心的只是文件的名称和修改时间,那么它会变得更有趣,但它仍然非常可行。

DirEntry

再次,如果你真的想要一个import std.algorithm; import std.array; import std.datetime; import std.file; import std.stdio; import std.typecons; void main(string[] args) { auto directoryToList = args[1]; auto files = dirEntries(directoryToList, SpanMode.shallow); auto pairs = array(map!(a => tuple(a.timeLastModified, a.name))(files)); sort!"a[0] < b[0]"(pairs); foreach(pair; pairs) writefln("%s: %s", pair[0], pair[1]); } ,那就去做time_t

这最终会创建一个Tuples数组,其中只包含时间和名称,然后只使用时间进行排序。

如果你对范围不是很熟悉,那么我建议你从D. D的标准库中使用范围很大的在线书籍上阅读this chapter,这可能就是为什么你觉得你有一个难以弄清楚如何在D. Ranges中做事情是一个非常强大的概念,但他们确实需要一些时间来适应。