如何惯用地/有效地将数据从 Read+Seek 传输到 Write? [英] How to idiomatically / efficiently pipe data from Read+Seek to Write?

查看:20
本文介绍了如何惯用地/有效地将数据从 Read+Seek 传输到 Write?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从输入文件中的随机位置获取数据,并按顺序将它们输出到输出文件.最好不要进行不必要的分配.

I want to take data from random locations in input file, and output them sequentially to output file. Preferably, with no unnecessary allocations.

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

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

Let's not worry about I/O latency here.

问题:

  1. 稳定的 Rust 是否有一些帮助程序可以从一个流中获取 x 个字节并将它们推送到另一个流?还是我必须自己滚动?
  2. 如果我必须自己动手,也许有更好的方法?

推荐答案

您正在寻找 io::copy:

You are looking for io::copy:

use std::io::{self, prelude::*, SeekFrom};

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

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

    Ok(())
}

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

If you look at the implementation of io::copy, you can see that it's similar to your code. However, it takes care to handle more error cases:

  1. write并非总是写出你要求的所有内容!
  2. 中断"写入通常不会致命.
  1. write does not always write everything you ask it to!
  2. An "interrupted" write isn't usually fatal.

它也使用更大的缓冲区大小,但仍然是堆栈分配.

It also uses a larger buffer size but still stack-allocates it.

这篇关于如何惯用地/有效地将数据从 Read+Seek 传输到 Write?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆