2015-01-21 8 views
5

Interfejs API we/wy dla plików w Phobos jest stosunkowo łatwy w użyciu, ale teraz mam wrażenie, że nie jest on dobrze zintegrowany z interfejsem zakresu D's.Jak stworzyć leniwy wyceniony zakres z pliku?

mógłbym stworzyć gamę ograniczającej całą zawartość czytając całą zawartość pliku do tablicy:

import std.file; 
auto mydata = cast(ubyte[]) read("filename"); 
processData(mydata); // takes a range of ubytes 

Ale to chętnie oceny danych może być niepożądana, jeśli chcę tylko odzyskać nagłówku pliku, do przykład. Parametr upTo nie rozwiązuje tego problemu, jeśli format pliku przyjmuje nagłówek o zmiennej długości lub dowolny inny element, który chcemy pobrać. Może nawet znajdować się w środku pliku, a read zmusza mnie do przeczytania całego pliku do tego momentu.

Ale rzeczywiście istnieją alternatywy. readf, readln, , a przede wszystkim byChunk pozwala mi pobierać fragmenty danych, aż dojdę do końca pliku lub tylko wtedy, gdy chcę przestać czytać plik.

import std.stdio; 
File file("filename"); 
auto chunkRange = file.byChunk(1000); // a range of ubyte[]s 
processData(chunkRange); // oops! not expecting chunks! 

Ale teraz wprowadziłem złożoność radzenia sobie z porcjami o stałej wielkości danych, zamiast ciągłego zakresu bajtów.

Jak zatem utworzyć prosty zakres wejściowy bajtów z pliku, który jest leniwy, czy to według znaków, czy małych fragmentów (w celu zmniejszenia liczby odczytów)? Czy zakres w drugim przykładzie może być płynnie hermetyzowany w taki sposób, że dane mogą być przetwarzane jak w pierwszym przykładzie?

Odpowiedz

7

Można użyć std.algorithm.joiner:

auto r = File("test.txt").byChunk(4096).joiner(); 

Zauważ, że byChunk ponownie wykorzystuje ten sam bufor dla każdego kawałka, więc może trzeba dodać .map!(chunk => chunk.idup) się leniwie skopiować kawałki na stercie.

+0

To wydaje się działać bez mapowania każdego fragmentu do jego własnej pamięci. W końcu 'InputRange' już oczekuje tylko na sekwencyjny jednorazowy odczyt. Czy możesz wymyślić przypadek, w którym jest to naprawdę potrzebne? –

+0

Być może nigdy nie jest potrzebne, jak mówisz. –