6

如何从文件中轻松构建原始的逐字节 InputRange/ForwardRange/RandomAccessRange?

4

2 回答 2

13
file.byChunk(4096).joiner

这会以 4096 字节的块读取文件,然后将这些块延迟连接到单个ubyte输入范围中。

joiner是 from std.algorithm,所以你必须先导入它。

于 2015-05-16T17:53:43.003 回答
7

从文件中创建原始字节范围的最简单方法是将其全部读入内存:

import std.file;
auto data = cast(ubyte[]) read("filename");
// data is a full-featured random access range of the contents

如果文件太大而不合理,您可以尝试使用内存映射文件http://dlang.org/phobos/std_mmfile.html并使用 opSlice 从中获取一个数组。由于它是一个数组,因此您可以获得全方位的功能,但由于它是由操作系统映射的内存,因此您在触摸文件时会变得懒惰阅读。

对于一个简单的 InputRange,LockingTextReaderPhobos 中有(未记录),或者您可以自己构建一个,byChunk甚至fgetc是 C 函数。fgetc将是最容易写的:

struct FileByByte {
    ubyte front;
    void popFront() { front = cast(ubyte) fgetc(fp); }
    bool empty() { return feof(fp); }
    FILE* fp;
    this(FILE* fp) { this.fp = fp; popFront(); /* prime it */ }
}

我还没有实际测试过,但我很确定它会起作用。(顺便说一句,文件打开和关闭与此分开,因为范围应该只是对数据的视图,而不是托管容器。您不希望文件因为您将此范围传递给函数而关闭。)

不过,这不是前向或随机访问范围。在没有大量缓冲代码的流上执行这些操作会比较棘手,我认为尝试编写这是一个错误 - 通常,范围应该很便宜,而不是模拟底层容器本身不支持的功能。

编辑:另一个答案有一个非缓冲方式!https://stackoverflow.com/a/30278933/1457000太棒了。

于 2015-05-16T12:57:58.537 回答