【发布时间】:2015-05-16 10:30:33
【问题描述】:
如何从文件中轻松构造原始的逐字节 InputRange/ForwardRange/RandomAccessRange?
【问题讨论】:
如何从文件中轻松构造原始的逐字节 InputRange/ForwardRange/RandomAccessRange?
【问题讨论】:
file.byChunk(4096).joiner
这会以 4096 字节的块读取文件,然后将这些块懒惰地连接到单个 ubyte 输入范围中。
joiner 来自std.algorithm,所以你必须先导入它。
【讨论】:
从文件中生成原始字节范围的最简单方法是将其全部读入内存:
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(未记录),或者您可以自己在 C 函数 byChunk 甚至 fgetc 上构建一个。 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 太棒了。
【讨论】: