2015-11-01 232 views
7

我想從輸入文件中的隨機位置獲取數據,並將它們順序輸出到輸出文件。優選地,沒有不必要的分配。如何地理/有效地從讀取+尋求寫入數據?

This is one kind of solution I have figured out

use std::io::{ self, SeekFrom, Cursor, Read, Write, Seek }; 

#[test] 
fn read_write() { 
    // let's say this is input file 
    let mut input_file = Cursor::new(b"worldhello"); 
    // and this is output file 
    let mut output_file = Vec::<u8>::new(); 

    assemble(&mut input_file, &mut output_file).unwrap(); 

    assert_eq!(b"helloworld", &output_file[..]); 
} 

// I want to take data from random locations in input file 
// and output them sequentially to output file 
pub fn assemble<I, O>(input: &mut I, output: &mut O) -> Result<(), io::Error> 
    where I: Read + Seek, O: Write 
{ 
    // first seek and output "hello" 
    try!(input.seek(SeekFrom::Start(5))); 
    let mut hello_buf = [0u8; 5]; 
    try!(input.take(5).read(&mut hello_buf)); 
    try!(output.write(&hello_buf)); 

    // then output "world" 
    try!(input.seek(SeekFrom::Start(0))); 
    let mut world_buf = [0u8; 5]; 
    try!(input.take(5).read(&mut world_buf)); 
    try!(output.write(&world_buf)); 

    Ok(()) 
} 

讓我們不要擔心I/O延遲在這裏。

問題:

  1. 是否穩定的鏽有一些幫手採取x字節從一個流並將它們推到另一個流?或者我必須推出自己的?
  2. 如果我必須自己推出,也許有更好的方法?
+2

無關:更改彙編以使用''而且它更通用(允許特質對象)。 – bluss

回答

4

您正在尋找io::copy

pub fn assemble<I, O>(input: &mut I, output: &mut O) -> Result<(), io::Error> 
    where I: Read + Seek, O: Write 
{ 
    // first seek and output "hello" 
    try!(input.seek(SeekFrom::Start(5))); 
    try!(io::copy(&mut input.take(5), output)); 

    // then output "world" 
    try!(input.seek(SeekFrom::Start(0))); 
    try!(io::copy(&mut input.take(5), output)); 

    Ok(()) 
} 

如果你看the implementation of io::copy,你可以看到,它類似於你的代碼。但是,它需要照顧,以處理更多的錯誤情況:

  1. write總是寫你問它的一切!
  2. 「中斷」寫入通常不是致命的。

它也使用較大的緩衝區大小,但仍然堆棧分配它。

相關問題