来自文件的字节输入范围

Byte InputRange from file

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

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

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,在 Phobos 中有 LockingTextReader(未记录),或者您可以在 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 */ }
}

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

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

编辑:另一个答案有一个非缓冲的方式! 太棒了。

file.byChunk(4096).joiner

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

joiner 来自 std.algorithm,因此您必须先导入它。