2015-05-16 8 views

risposta

13
file.byChunk(4096).joiner 

Questa legge un file in blocchi di 4096 byte e si unisce pigramente i pezzi insieme in un unico intervallo ubyte di ingresso.

joiner è da std.algorithm, quindi è necessario importarlo prima.

+2

Vorrei poter sopravvivere cinque volte, è super utile e non lo sapevo! –

+0

@ AdamD.Ruppe sembra un buon argomento per questa settimana in D! –

+0

Immagina questo avvolto in un futuro, e ricevi un evento solo quando i dati sono caricati ... Roba buona. – DejanLekic

7

Il modo più semplice per fare un intervallo di byte prima da un file è quello di leggere proprio tutto a posto in memoria:

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

Se il file è troppo grande per che per essere ragionevole, si potrebbe provare un ricordo -mapped file http://dlang.org/phobos/std_mmfile.html e utilizzare opSlice per ottenere un array spento. Poiché si tratta di un array, si ottengono funzionalità a gamma intera, ma poiché è mappato in memoria dal sistema operativo, si ottiene una lettura lenta quando si tocca il file.

Per una semplice InputRange, c'è LockingTextReader (non documentato) in Phobos, oppure si potrebbe costruire uno voi stessi nel corso byChunk o addirittura fgetc, la funzione C. fgetc sarebbe il più facile da scrivere:

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

Non ho effettivamente testato questo, ma sono abbastanza sicuro che sarebbe lavoro. (BTW il file aperto e chiuso è separato da questo perché le gamme dovrebbero essere solo viste in dati, non contenitori gestiti. Non vorrai che il file venga chiuso solo perché hai passato questo intervallo in una funzione.)

è non tuttavia un intervallo di accesso diretto o casuale. Quelle sono più difficili da fare sugli stream senza un sacco di codice di buffering e penso che sarebbe un errore cercare di scrivere - in generale, gli intervalli dovrebbero essere economici, non emulando caratteristiche che il contenitore sottostante non supporta nativamente.

MODIFICA: l'altra risposta ha un modo non buffering! https://stackoverflow.com/a/30278933/1457000 È fantastico.