【发布时间】:2020-04-01 04:01:07
【问题描述】:
我正在尝试实现https://github.com/pingcap/talent-plan/blob/master/rust/building-blocks/bb-2.md 的最后一个练习。
简而言之,我需要将一些枚举序列化为 bson,写入文件并从文件中读取它们。 我一直在检查是否达到 EOF。我用谷歌搜索了一段时间,但没有找到答案。
use std::path::Path;
use std::fs::{create_dir_all, OpenOptions};
use std::io::{Write, Seek, Cursor, SeekFrom};
use serde::{Serialize, Deserialize};
use std::str;
use bson;
use bson::{encode_document, decode_document};
fn main() {
let dir = Path::new("D:/download/rust");
create_dir_all(dir).expect("Cannot create dir");
let txt = dir.join("move.txt");
// Encode some moves
let mut file = OpenOptions::new()
.append(true)
.create(true)
.open(&txt)
.expect("Cannot open txt");
encode_and_write_move(&mut file, &Move::Up(1));
encode_and_write_move(&mut file, &Move::Down(2));
encode_and_write_move(&mut file, &Move::Left(3));
encode_and_write_move(&mut file, &Move::Right(4));
// Decode and print moves
let mut file = OpenOptions::new()
.read(true)
.open(&txt)
.expect("Cannot open txt");
loop {
let end_of_file = false; // How?
if end_of_file {
break;
}
let doc = decode_document(&mut file).expect("cannot decode doc");
println!("doc = {:?}", doc);
}
}
fn encode_and_write_move<W: Write>(writer: &mut W, mov: &Move) {
let serialized = bson::to_bson(mov).unwrap();
let doc = serialized.as_document().unwrap();
encode_document(writer, doc).expect("failed to encode doc");
}
#[derive(Debug, Serialize, Deserialize)]
enum Move {
Up(i32),
Down(i32),
Left(i32),
Right(i32),
}
更新:
似乎查看是否达到 EOF 的唯一方法是检查返回的 Err。这是我对整个练习的尝试。
use std::path::Path;
use std::fs::{create_dir_all, OpenOptions};
use std::io::Write;
use serde::{Serialize, Deserialize};
use std::{str, io};
use bson;
use bson::{encode_document, decode_document, DecoderError};
fn main() {
let dir = Path::new("D:/download/rust");
create_dir_all(dir).expect("Cannot create dir");
let txt = dir.join("move.txt");
// Encode some moves
let mut writer = OpenOptions::new()
.append(true)
.create(true)
.open(&txt)
.expect("Cannot open txt");
encode_and_write_move(&mut writer, &Move::Up(1));
encode_and_write_move(&mut writer, &Move::Down(2));
encode_and_write_move(&mut writer, &Move::Left(3));
encode_and_write_move(&mut writer, &Move::Right(4));
// Decode and print moves
let mut reader = OpenOptions::new()
.read(true)
.open(&txt)
.expect("Cannot open txt");
loop {
match decode_document(&mut reader) {
Result::Ok(doc) => println!("doc = {:?}", &doc),
Result::Err(DecoderError::IoError(e)) if e.kind() == io::ErrorKind::UnexpectedEof => break,
Result::Err(err) => panic!("Decoding failed with {}", err)
}
}
}
fn encode_and_write_move<W: Write>(writer: &mut W, mov: &Move) {
let serialized = bson::to_bson(mov).unwrap();
let doc = serialized.as_document().unwrap();
encode_document(writer, doc).expect("failed to encode doc");
}
#[derive(Debug, Serialize, Deserialize)]
enum Move {
Up(i32),
Down(i32),
Left(i32),
Right(i32),
}
【问题讨论】:
-
为什么是EOF?我猜你只需要检查从
decode_document返回的DecoderResult。 -
@aventurin 请参阅我对以下 muhuk 的回答的回复