io - 如何惯用/高效地将数据从 Read+Seek 传输到 Write?

标签 io pipe rust

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

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

最佳答案

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

如果你看the implementation of io::copy ,您可以看到它与您的代码相似。但是,它需要注意处理更多的错误情况:

  1. write 总是写下您要求的一切!
  2. “中断”写入通常不会致命。

它还使用了更大的缓冲区大小,但仍对其进行堆栈分配。

关于io - 如何惯用/高效地将数据从 Read+Seek 传输到 Write?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51514138/

相关文章:

Java Swing Web 浏览器如何注意到 URL 不存在?

c++ - 混合 fstream 和 stdio 有技术上的危险吗?

python - 我如何使用 Tornado 提供(永无止境的)系统调用

C壳: Program hanging in first child

仅当通过文件接收(非用户)输入时才执行的 Java 程序

asynchronous - 如何有条件地退还不同类型的 future ?

java - 将字符串写入文件中的特定位置

bash - 使用 throttle 将文件通过管道传输到标准输入

rust - 如何将类型存储在数组中?

google-sheets - 如何使用google_sheets4条板箱构造适当的values_update调用?