2015-05-23 12 views
8

Mam strukturę z BufStream<T>, gdzie T: Read+Write. BufStream może być TcpStream i chciałbym przeczytać n bajtów z niego. Nie jest to ustalona ilość bajtów w predefiniowanym buforze, ale mam ciąg/strumień, który wskazuje liczbę bajtów do odczytu następnej.Jak odczytać określoną liczbę bajtów ze strumienia?

Czy jest to dobry sposób na zrobienie tego?

Odpowiedz

3

Brzmi jak chcesz Read::take i Read::read_to_end:

use std::io::prelude::*; 
use std::io::BufReader; 
use std::str; 

fn read_n<R>(reader: R, bytes_to_read: u64) -> Vec<u8> 
where 
    R: Read, 
{ 
    let mut buf = vec![]; 
    let mut chunk = reader.take(bytes_to_read); 
    // Do appropriate error handling for your situation 
    let n = chunk.read_to_end(&mut buf).expect("Didn't read enough"); 
    assert_eq!(bytes_to_read as usize, n); 
    buf 
} 

fn main() { 
    let input_data = b"hello world"; 
    let mut reader = BufReader::new(&input_data[..]); 

    let first = read_n(&mut reader, 5); 
    let _ = read_n(&mut reader, 1); 
    let second = read_n(&mut reader, 5); 

    println!(
     "{:?}, {:?}", 
     str::from_utf8(&first), 
     str::from_utf8(&second) 
    ); 
} 
+0

Dzięki .. nie bierze() konsumować czytelnika? Moim przypadkiem jest to, że mam tcpstream (część struktury), z którego czytam linie. Czasami pomiędzy nie muszę czytać linii, ale określoną ilość bajtów. Potem będę musiał ponownie przeczytać linie ... – buster

+1

Tak, ale "czytnik" może być '' mut ', tzn. Tymczasowym zmiennym odniesieniem do innego czytnika. Take używa API o wartości dodanej, dzięki czemu wszystkie przypadki użycia są obsługiwane. Ten model pojawia się w różnych narożnikach rdzy. – bluss

+0

@buster jak blus wskazuje, '& mut R' również implementuje cechę' Read'. Mój przykład wykorzystuje to z dobrym skutkiem - dlatego przekazuję w '' & mut reader' w głównej metodzie przykładu. – Shepmaster

4

Od Rust 1.6 Read::read_exact mogą być wykorzystywane do tego celu. Jeśli bytes_to_read jest liczba bajtów trzeba czytać, ewentualnie określonych w czasie wykonywania, a reader jest strumień czytać od:

let mut buf = vec![0u8; bytes_to_read]; 
reader.read_exact(&mut buf)?; 

część, która nie była dla mnie jasne, z dokumentacji read_exact było to, że cel bufor może być dynamicznie przydzielany Vec.

Dzięki społeczności Rust Gitter za wskazanie mi tego rozwiązania.

Powiązane problemy