来自文件的字节InputRange

时间:2015-05-16 10:30:34

标签: file-io d phobos

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

2 个答案:

答案 0 :(得分:13)

file.byChunk(4096).joiner

以4096字节的块读取文件,并懒惰地将块连接到一个ubyte输入范围。

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

答案 1 :(得分: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,在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 */ }
}

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

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

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