2015-05-23 4 views
8

Ich habe eine Struktur mit einer BufStream<T> wo T: Read+Write. Die BufStream kann eine TcpStream sein und ich möchte n Bytes davon lesen. Nicht eine feste Anzahl von Bytes in einem vordefinierten Puffer, aber ich habe einen String/Stream, der die Anzahl der Bytes angibt, die als nächstes zu lesen sind.Wie lese ich eine bestimmte Anzahl von Bytes aus einem Stream?

Gibt es eine nette Möglichkeit, das zu tun?

Antwort

3

Es klingt wie Sie Read::take und Read::read_to_end wollen:

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

Danke .. nicht nehmen() den Leser verbrauchen? Mein Anwendungsfall ist, dass ich einen tcpstream (Teil einer Struktur) habe, von dem ich Zeilen lese. Manchmal muss ich keine Zeile lesen, sondern eine bestimmte Anzahl an Bytes. Danach muss ich wieder Zeilen lesen ... – buster

+1

Es tut, aber "der Leser" kann ein "& mut R" sein, d. H. Eine temporäre veränderbare Referenz zu einem anderen Leser. Take verwendet eine Wert-API, sodass alle Anwendungsfälle unterstützt werden. Dieses Modell erscheint in einigen verschiedenen Ecken des Rosts. – bluss

+0

@buster as bluss weist darauf hin, '& mut R' implementiert auch das Merkmal' Read'. Mein Beispiel benutzt das sehr gut - deshalb gebe ich in der Hauptmethode des Beispiels "& mut reader" ein. – Shepmaster

4

Seit Rust 1.6, Read::read_exact verwendet werden kann, dies zu tun. Wenn bytes_to_read die Anzahl von Bytes, die Sie lesen müssen, möglicherweise zur Laufzeit bestimmt, und reader ist der Strom lesen von:

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

Der Teil, der mir nicht klar, von der read_exact Dokumentation war, dass das Ziel Puffer kann dynamisch zugewiesen werden Vec.

Danke an die Rustgitter-Community, die mich auf diese Lösung hingewiesen hat.

Verwandte Themen