2015-05-23 13 views
8

Tôi có cấu trúc với một số BufStream<T> trong đó T: Read+Write. BufStream có thể là TcpStream và tôi muốn đọc n byte từ đó. Không phải số byte cố định trong bộ đệm được xác định trước, nhưng tôi có một chuỗi/luồng cho biết số byte để đọc tiếp theo.Cách đọc số byte cụ thể từ luồng?

Có cách nào tốt đẹp để làm điều đó không?

Trả lời

3

Có vẻ như bạn muốn Read::takeRead::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

Cảm ơn .. không dùng() tiêu thụ người đọc? Usecase của tôi là tôi có một tcpstream (một phần của một cấu trúc) mà từ đó tôi đọc dòng. Đôi khi ở giữa tôi không cần phải đọc một dòng nhưng một số tiền cụ thể của byte. Sau đó tôi sẽ cần phải đọc lại dòng ... – buster

+1

Nó có, nhưng "người đọc" có thể là một '& mut R' tức là một tham chiếu tạm thời có thể thay đổi được với một trình đọc khác. Sử dụng API theo giá trị để tất cả các trường hợp sử dụng đều được hỗ trợ. Mô hình này xuất hiện ở một số góc rỉ sét khác nhau. – bluss

+0

@buster như bluss chỉ ra, '& mut R' cũng thực hiện các đặc điểm' Read'. Ví dụ của tôi sử dụng điều đó để có hiệu quả tốt - đó là lý do tại sao tôi truyền vào '& mut reader' trong phương pháp chính của ví dụ. – Shepmaster

4

Kể từ Rust 1.6, Read::read_exact có thể được sử dụng để làm điều này. Nếu bytes_to_read là số byte bạn cần phải đọc, có thể xác định tại thời gian chạy, và reader là dòng để đọc từ:

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

Phần đó không phải là rõ ràng với tôi từ tài liệu read_exact là mục tiêu bộ đệm có thể được phân bổ động Vec.

Nhờ cộng đồng Rust Gitter đã chỉ cho tôi giải pháp này.

Các vấn đề liên quan