如何从文件中轻松构造原始的逐字节InputRange / ForwardRange / RandomAccessRange?
答案 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那太棒了。