如何以惯用/有效的方式将数据从Read + Seek转换为Write? [英] How to idiomatically / efficiently pipe data from Read+Seek to Write?
本文介绍了如何以惯用/有效的方式将数据从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.
问题:
- 稳定的Rust有一些帮助从一个流中获取x个字节并将它们推送到另一个流?或者我必须自己滚动?
- 如果我必须自己动手,也许有更好的方法?
推荐答案
您正在寻找 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:
-
写
不总是写下你要求的所有内容! - 中断写作通常不会致命。
write
does not always write everything you ask it to!- An "interrupted" write isn't usually fatal.
它还使用更大的缓冲区大小但仍然堆栈分配它。
It also uses a larger buffer size but still stack-allocates it.
这篇关于如何以惯用/有效的方式将数据从Read + Seek转换为Write?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文