2016-12-09 3 views

Répondre

13

En fait, il y a un moyen. Rencontrez Cursor<T>!

Dans la documentation, vous pouvez voir qu'il ya les impls suivantes:

impl<T> Seek for Cursor<T> where T: AsRef<[u8]> 
impl<T> Read for Cursor<T> where T: AsRef<[u8]> 
impl Write for Cursor<Vec<u8>> 
impl<T> AsRef<[T]> for Vec<T> 

De cela, vous pouvez voir que vous pouvez utiliser le type Cursor<Vec<u8>> comme un fichier ordinaire, parce Read, Write et Seek sont implémentés pour ce type!

exemple Little (Playground):

use std::io::{Cursor, Read, Seek, SeekFrom, Write}; 

// Create fake "file" 
let mut c = Cursor::new(Vec::new()); 

// Write into the "file" and seek to the beginning 
c.write_all(&[1, 2, 3, 4, 5]).unwrap(); 
c.seek(SeekFrom::Start(0)).unwrap(); 

// Read the "file's" contents into a vector 
let mut out = Vec::new(); 
c.read_to_end(&mut out).unwrap(); 

println!("{:?}", out); 

Pour un exemple plus utile, consultez la documentation liée ci-dessus.

1

Si vous souhaitez utiliser BufReader avec en mémoire String, vous pouvez utiliser la méthode as_bytes():

use std::io::BufRead; 
use std::io::BufReader; 
use std::io::Read; 

fn read_buff<R: Read>(mut buffer: BufReader<R>) { 
    let mut data = String::new(); 
    let _ = buffer.read_line(&mut data); 

    println!("read_buff got {}", data); 
} 

fn main() { 
    read_buff(BufReader::new("Potato!".as_bytes())); 
} 

Imprime read_buff got Potato!. Il n'est pas nécessaire d'utiliser un curseur pour ce cas. Pour utiliser un String en mémoire avec BufWriter, vous pouvez utiliser la méthode as_mut_vec. Malheureusement, il est unsafe et je n'ai trouvé aucun autre moyen. Je n'aime pas l'approche Cursor car il consomme le vecteur et je n'ai pas encore trouvé un moyen d'utiliser le Cursor avec BufWriter.

use std::io::BufWriter; 
use std::io::Write; 

pub fn write_something<W: Write>(mut buf: BufWriter<W>) { 
    buf.write("potato".as_bytes()); 
} 

#[cfg(test)] 
mod tests { 
    use super::*; 
    use std::io::{BufWriter}; 

    #[test] 
    fn testing_bufwriter_and_string() { 
     let mut s = String::new(); 

     write_something(unsafe { BufWriter::new(s.as_mut_vec()) }); 

     assert_eq!("potato", &s); 
    } 
} 
+0

Vous pouvez [obtenir le 'Vec' retour] (https://doc.rust-lang.org/std/io/struct.Cursor.html#method.into_inner) une fois que vous avez terminé avec le' Curseur – Shepmaster

+0

@Shepmaster Génial! Et puis je peux utiliser ['from_utf8'] (https://doc.rust-lang.org/std/str/fn.from_utf8.html) pour convet à String,' from_utf8' semble éviter la copie du vecteur de sorte qu'il devrait être efficace, pourrait également utiliser le 'from_utf8_unchecked 'qui devrait être un simple mouvement. –