Rust has two traits for dealing with I/O: Read
and Write
. Generally, you'll create a reader and a writer, then use copy
to move bytes from one to the other. Or if you are going to/from memory, you'll use whatever function in your situation takes a reader/writer and call that.
For serializing rust data, you need to decide on a serialization format. I'll use JSON because it's easy to read, but you'll probably want something else if you want space efficiency, although compression should make any format mostly the same.
The most important serialization library is serde, which is explained more in this question. Annotate your struct with the derive macros for Serialize
and Deserialize
.
serde_json has the to_writer
function, which takes a serde-compatible type and writes it out in JSON to a writer. You have the data, so now you need a writer.
The zstd crate has an Encoder
, which is a writer that wraps another writer. That other writer will just be a File
. Then you simply give the writer and the data to to_writer
.
// Open the file
let writer = File::create("temp.json.zstd")?;
// Wrap the file in the zstd encoder
let writer = zstd::Encoder::new(writer, 0)?.auto_finish();
// Write the data into the encoder
serde_json::to_writer(writer, &data)?;
Note that you can pass &mut writer
if you wanted to keep it afterwards. Also note that writing/reading data unbuffered to/from a file is very slow. Fortunately, zstd buffers both sides by default so you don't need to wrap your file in a BufWriter
/BufReader
manually.
Then reading the file is much the same, but with the Decoder
and from_reader
instead.
// Open the file
let reader = File::open("temp.json.zstd")?;
// Wrap the file in the zstd decoder
let reader = zstd::Decoder::new(reader)?;
// Read the data from the decoder
let data: Vec<Data> = serde_json::from_reader(reader)?;