如何从文件中轻松构造原始的逐字节InputRange/ForwardRange/RandomAccessRange?
Col*_*Two 13
file.byChunk(4096).joiner
Run Code Online (Sandbox Code Playgroud)
它以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
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/这太棒了.