我需要一個完全內存中的對象,我可以給BufReader
和BufWriter
。像Python的StringIO
。我想使用通常與File
s一起使用的方法來寫入和讀取這樣的對象。如何創建可用作Rust中的Reader或Writer的內存中對象?
有沒有辦法使用標準庫來做到這一點?
我需要一個完全內存中的對象,我可以給BufReader
和BufWriter
。像Python的StringIO
。我想使用通常與File
s一起使用的方法來寫入和讀取這樣的對象。如何創建可用作Rust中的Reader或Writer的內存中對象?
有沒有辦法使用標準庫來做到這一點?
其實有一種方法。 遇見Cursor<T>
!
在文檔可以看到還有以下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>
從這可以看到可以使用類型Cursor<Vec<u8>>
就像普通文件因爲Read
,Write
和Seek
是爲該類型實現的!
小例子(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);
對於更有用的例子,檢查上面鏈接的文檔。
如果你想使用BufReader
與內存String
,您可以使用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()));
}
這將打印read_buff got Potato!
。這種情況下不需要使用遊標。
要使用內存String
和BufWriter
,可以使用as_mut_vec
方法。不幸的是它是unsafe
,我還沒有找到任何其他方式。我不喜歡Cursor
的方法,因爲它消耗了矢量,我還沒有找到一種方法來將Cursor
與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);
}
}
您可以[拿到'Vec'回(https://doc.rust-lang.org/std/io/struct.Cursor.html#method.into_inner)你與完成後的' Cursor'。 – Shepmaster
@Shepmaster太棒了!然後我可以使用['from_utf8'](https://doc.rust-lang.org/std/str/fn.from_utf8.html)傳遞給String,'from_utf8'似乎避免了複製矢量,所以它應該是高效的,也可以強制使用'from_utf8_unchecked'這應該是一個簡單的舉動。 –