InputRange byte from file

How to easily build the original byte byte of InputRange / ForwardRange / RandomAccessRange from a file?

+6
source share
2 answers
file.byChunk(4096).joiner 

This reads the file in 4096 byte fragments and lazily combines the pieces into a single ubyte input range.

joiner is from std.algorithm , so you have to import it first.

+13
source

The easiest way to make the original range of bytes from a file is to simply read it all in memory:

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

If the file is too large to make sense, you can try the memory mapping file http://dlang.org/phobos/std_mmfile.html and use opSlice to get an array from it. Since this is an array, you get full-featured functions, but since it is the memory displayed by the operating system, you get lazy reading when you touch the file.

For a simple InputRange, there is a LockingTextReader (undocumented) in Phobos, or you can build it yourself on byChunk or even fgetc , the C. fgetc function would be easiest to write:

 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 */ } } 

I really have not tested this, but I'm sure it will work. (BTW open and close the file separately from this, because ranges should be just views in the data, not managed containers. You would not want the file to be closed only because you passed this range to the function.)

However, this is not a direct and arbitrary range of access. This is more difficult to do in streams without a lot of buffering code, and I think it would be a mistake to try to write - usually ranges should be cheap and not emulating functions that the base container does not support.

EDIT: another answer has a non-buffering way! fooobar.com/questions/987330 / ... This is awesome.

+7
source

Source: https://habr.com/ru/post/987330/


All Articles