如何从Read + Seek到地道/有效地管道数据写入?

我想从输入文件的随机位置获取数据,并将它们顺序输出到输出文件。 优选地,没有不必要的分配。

这是我已经想出的一种解决方案:

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延迟。

问题:

  • 稳定的Rust是否有一些帮助从一个流中取出x个字节并将它们推送到另一个流? 或者我必须推出自己的?
  • 如果我必须推出自己的产品,或许有更好的方法?

  • 你正在寻找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(())
    }
    

    如果你看看io::copy的实现,你可以看到它和你的代码很相似。 但是,它需要处理更多的错误情况:

  • write 总是写你问它的一切!
  • “中断”写入通常不是致命的。
  • 它也使用更大的缓冲区大小,但仍然是堆栈分配它。

    链接地址: http://www.djcxy.com/p/88569.html

    上一篇: How to idiomatically / efficiently pipe data from Read+Seek to Write?

    下一篇: Why some Boost functions don't need prefixing with namespace