2016-12-09 44 views

Odpowiedz

13

W rzeczywistości istnieje sposób. Poznaj Cursor<T>!

W dokumentacji można zobaczyć, że istnieją następujące impls:

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> 

Z tego widać, że można użyć typu Cursor<Vec<u8>> tylko jako zwykły plik, ponieważ Read, Write i Seek są zaimplementowane dla tego typu!

mały przykład (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); 

Dla bardziej użyteczny przykład sprawdzić dokumentację związaną powyżej.

1

Jeśli chcesz użyć BufReader z in-memory String, można użyć metody 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())); 
} 

ten drukuje read_buff got Potato!. W tym przypadku nie ma potrzeby używania kursora.

Aby użyć wbudowanej pamięci String z BufWriter, można użyć metody as_mut_vec. Niestety jest to unsafe i nie znalazłem żadnego innego sposobu. Nie podoba mi się podejście Cursor, ponieważ zużywa ono wektor i nie znalazłem jeszcze sposobu na użycie Cursor razem z 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

Można [wykonania swojej 'Vec' powrót] (https://doc.rust-lang.org/std/io/struct.Cursor.html#method.into_inner) po zakończeniu z' Kursor'. – Shepmaster

+0

@Shepmaster Great! A potem mogę użyć ['from_utf8'] (https://doc.rust-lang.org/std/str/fn.from_utf8.html), aby przekonwertować do String,' from_utf8' wydaje się unikać kopiowania wektora, więc powinna być wydajna, mogłaby również z powodzeniem używać polecenia 'from_utf8_unchecked ', które powinno być prostym ruchem. –