如何从文件创建 lazy-evaluated 范围?

How to create a lazy-evaluated range from a file?

Phobos中的File I/O API还是比较好用的,但是现在感觉和D的range界面结合得不是很好

我可以通过将整个文件读入数组来创建一个分隔全部内容的范围:

import std.file;
auto mydata = cast(ubyte[]) read("filename");
processData(mydata); // takes a range of ubytes

但是,例如,如果我只想检索文件的 header,则可能不需要这种急切的数据评估。如果文件格式采用 variable-length header 或我们希望检索的任何其他元素,则 upTo 参数无法解决此问题。它甚至可能在文件的中间,read 迫使我阅读到那一点的所有文件。

但确实有其他选择。 readfreadlnbyLine 尤其是 byChunk 让我可以检索数据片段,直到我到达文件末尾,或者当我想停止读取文件时.

import std.stdio;
File file("filename");
auto chunkRange = file.byChunk(1000); // a range of ubyte[]s
processData(chunkRange); // oops! not expecting chunks!

但现在我已经介绍了处理固定大小的数据块而不是连续的字节范围的复杂性。

那么我如何从一个惰性评估的文件中创建一个简单的字节输入范围,无论是按字符还是按小块(以减少读取次数)?第二个例子中的范围是否可以像第一个例子那样无缝封装成可以处理数据的方式?

您可以使用 std.algorithm.joiner:

auto r = File("test.txt").byChunk(4096).joiner();

请注意,byChunk 为每个块重复使用相同的缓冲区,因此您可能需要添加 .map!(chunk => chunk.idup) 以延迟将块复制到堆中。