2016-05-06 12 views
7

Jaki jest najbardziej efektywny ogólny sposób czytania "dużych" plików (które mogą być tekstowe lub binarne), bez wchodzenia na terytorium unsafe? Byłem zaskoczony, jak mało istotnych wyników było, gdy zrobiłem wyszukiwanie w Internecie "rdzy czytać duży plik w kawałkach".Najbardziej efektywny sposób odczytywania dużych plików w kawałkach

Na przykład jedna z moich przypadków użycia jest do obliczania sum kontrolnych MD5 dla pliku przy użyciu rust-crypto (moduł Md5 pozwala na dodawanie &[u8] kawałki iteracyjnie).

Oto co mam, co wydaje się wykonać nieco lepiej niż w niektórych innych metod, takich jak read_to_end:

const CAP: usize = 1024 * 128; 
let mut file = try!(File::open("my.file")); 
let mut reader = BufReader::with_capacity(CAP, file); 

loop { 
    let length = { 
     let buffer = try!(reader.fill_buf()); 
     // do stuff with buffer here 
     buffer.len() 
    }; 
    if length == 0 { break; } 
    reader.consume(length); 
} 

Odpowiedz

6

Nie sądzę, można napisać kod bardziej wydajne niż. fill_buf na BufReader przez File to po prostu proste połączenie z read(2). Zobacz https://github.com/rust-lang/rust/blob/e1195c24bb567019d7cdc65bf5a4c642e38475d1/src/libstd/io/buffered.rs#L185.

To powiedziawszy, BufReader nie jest tak naprawdę użyteczną abstrakcją, gdy używa się jej w ten sposób; prawdopodobnie będzie mniej kłopotliwe, po prostu zadzwoń bezpośrednio pod numer file.read(&mut buf).

+0

Dzięki za odpowiedź! Pomyślałem, że "BufReader" był dla mnie użyteczny, ponieważ zmienił rozmiar bufora dla mnie, kiedy dotarłem do końca czytnika, ale po prostu zdałem sobie sprawę, że to dość trywialne ... –

+2

* od czasu zmiany rozmiaru bufora * - wątpię, że zmienia rozmiar bufora, ale fragment jest prawdopodobnie skrócony, aby odzwierciedlić liczbę odczytanych bajtów. Ale masz rację, że zwracana wartość 'Read :: read' mówi, ile bufora jest prawidłowa. Jest to ** bardzo ważne **, aby użyć tego, w przeciwnym razie możesz dostać się do problemu takiego jak Heartbleed, gdzie bufor jest ponownie wykorzystywany ze starą zawartością! To może być dobry powód, aby użyć 'BufReader'. – Shepmaster

+0

Przepraszam, masz rację, miałem na myśli "skrócenie długości bufora". –

Powiązane problemy