2015-11-01 157 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. “中断”写入通常不是致命的。

它也使用较大的缓冲区大小,但仍然堆栈分配它。

相关问题