来自文件的字节InputRange

Tam*_*mas 6 file-io d phobos

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

Col*_*Two 13

file.byChunk(4096).joiner
Run Code Online (Sandbox Code Playgroud)

它以4096字节块的形式读取文件,并懒惰地将块连接在一起成为单个ubyte输入范围.

joiner来自std.algorithm,所以你必须先导入它.

  • 我希望我可以投票五次,这是非常有用的,我不知道! (2认同)

Ada*_*ppe 7

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

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

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

对于一个简单的InputRange,LockingTextReader在Phobos中有(未记录的),或者你可以自己构建一个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 */ }
}
Run Code Online (Sandbox Code Playgroud)

我实际上没有测试过,但我很确定它能正常工作.(BTW文件打开和关闭是独立的,因为范围应该只是数据的视图,而不是托管容器.您不希望文件因为您将此范围传递给函数而关闭.)

但这不是前向或随机访问范围.在没有大量缓冲代码的情况下对流做起来比较棘手,我认为尝试编写是错误的 - 通常,范围应该是便宜的,而不是模拟底层容器本身不支持的功能.

编辑:另一个答案是非缓冲方式!/sf/answers/2119525341/这太棒了.