如何从文件创建惰性评估范围?

E_n*_*ate 5 file-io d

Phobos中的File I/O API相对易于使用,但是现在我觉得它与D的范围界面没有很好的集成.

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

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

但是,如果我只想检索文件的标题,那么这种对数据的热切评估可能是不受欢迎的.upTo如果文件的格式采用可变长度标头或我们希望检索的任何其他元素,则该参数不能解决此问题.它甚至可能位于文件的中间,并read迫使我在此之前读取所有文件.

但事实上,还有其他选择.readf,readln,byLine最特别byChunk让我找回数据块,直到我到达文件的末尾,或者只是当我想停止读取文件.

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

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

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

Vla*_*eev 7

你可以使用std.algorithm.joiner:

auto r = File("test.txt").byChunk(4096).joiner();
Run Code Online (Sandbox Code Playgroud)

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