是否可以使用Writer
并将内容写回给写作者?像BufWriterReader
一样?我已经尝试过了,但是没有编译:
#[test]
fn write_to_json_test0() {
let json = get_schema_without_optionals0(); // this is a thing serde_json can (de)serialize
let buf = Vec::new();
let writer = BufWriter::new(buf); // buf moves here
serde_json::to_writer(writer, &json).unwrap(); // writer moves here
let s = String::from_utf8(writer.into_inner().unwrap()).unwrap(); // compile error, because writer used after move
assert_eq!(s, json.to_string());
}
有a pull-request for a BufWriter::buffer()
,但现在不可用。
测试to_string()
和to_writer()
是否返回相同值的最快方法是什么?我真的需要写文件并将文件读取为字符串吗?
答案 0 :(得分:3)
测试
to_string()
和to_writer()
是否返回相同值的最快方法
看the source code for to_string
:
let vec = try!(to_vec(value));
let string = unsafe {
// We do not emit invalid UTF-8.
String::from_utf8_unchecked(vec)
};
Ok(string)
打给to_vec
的人:
let mut writer = Vec::with_capacity(128);
try!(to_writer(&mut writer, value));
Ok(writer)
粘在一起,几乎与您的代码相同:
let mut writer = Vec::with_capacity(128);
to_writer(&mut writer, value)?;
let string = unsafe {
// We do not emit invalid UTF-8.
String::from_utf8_unchecked(writer)
};
Ok(string)
但是效率更高:
Vec
BufWriter
(如
Sven Marnach points out)对
BufWriter::buffer()
的拉取请求
否,在合并并释放该拉取请求之前,您无法访问BufWriter
的缓冲区-这是添加该请求的部分原因!
写给这位作家
您似乎并不完全了解BufWriter
的目的。它缓冲写入您的数据,以便基础写入器不获得它。缓冲区中的数据是基础编写器未看到的数据。您引用的请求请求不会帮助您。
实际上,在尝试将基础flush
解析为字符串之前,您需要确保BufWriter
Vec
以确保缓冲区中没有数据。幸运的是,into_inner
已经为您做到了。
作家搬到这里
这是因为Serde遵循“ C-RW-VALUE”准则:Generic reader/writer functions take R: Read
and W: Write
by value。您可以使用Write::by_ref
来避免放弃作者的所有权:
#[test]
fn write_to_json_test0() -> Result<(), io::Error> {
let json = Value::Number(42.into());
let buf = Vec::new();
let mut writer = BufWriter::new(buf);
serde_json::to_writer(writer.by_ref(), &json)?;
let s = String::from_utf8(writer.into_inner()?).unwrap();
assert_eq!(s, json.to_string());
Ok(())
}
之所以可行,是因为by_ref
返回了对编写者的可变引用,并且any mutable reference to a type that itself implements Write
的Write
有一个空白实现:
impl<'a, W: Write + ?Sized> Write for &'a mut W
by_ref
只是一种便利功能,可以避免显式地获取可变引用的相对奇怪的语法。 by_ref
和Read
都重复这种Iterator
模式。
另请参阅:
答案 1 :(得分:2)
有一个forwarding implementation of Write
for mutable references to Write
:
impl<'a, W: Write + ?Sized> Write for &'a mut W
使用此实现,您可以通过移动可变引用来避免移动buf
或移动writer
。
请注意,将Vec<u8>
包裹在BufWriter
中并不是很有用。缓冲旨在减少对慢速后端的写入次数,但是无论如何,如果后端是内存,那么添加一层缓冲都不会有任何好处。
如果我们删除BufWriter
,则您的代码应如下所示:
fn write_to_json_test0() {
let json = get_schema_without_optionals0();
let mut buf = Vec::new();
serde_json::to_writer(&mut buf, &json).unwrap();
let s = String::from_utf8(buf).unwrap();
assert_eq!(s, json.to_string());
}