io pipe rust

¿Cómo canalizar los datos de forma idiomática/eficiente desde Read+Seek to Write?



pipe rust (1)

Usted está buscando 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(()) }

Si observa la implementación de io::copy , puede ver que es similar a su código. Sin embargo, se encarga de manejar más casos de error:

  1. write no siempre escribe todo lo que le pides!
  2. Una escritura "interrumpida" no suele ser fatal.

También usa un tamaño de búfer más grande, pero aún así se asigna en pila.

Quiero tomar datos de ubicaciones aleatorias en el archivo de entrada y enviarlos secuencialmente al archivo de salida. Preferiblemente, sin asignaciones innecesarias.

Este es un tipo de solución que he descubierto :

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(()) }

No nos preocupemos por la latencia de E / S aquí.

Preguntas:

  1. ¿Tiene el establo Rust algún ayudante para tomar x bytes de una secuencia y empujarlos a otra secuencia? ¿O tengo que hacer mi propio?
  2. Si tengo que rodar el mío, tal vez hay una mejor manera?