Serialize结构体列表并以BSON格式写入文件,然后反序列化回结构体。

huangapple go评论91阅读模式
英文:

Rust : Serialize the list of structs and write in a file in BSON format and deserialize back to struct

问题

I am trying to convert a list of structs and write them to a file in BSON format and deserialize them back to a struct. I am using the following crate:

  1. bson = { version="2.6.0" }

I converted my list of structs to BSON, and then tried to find a way to convert the BSON to vec[u8], but I didn't find any.

I need to store BSON in their binary format only to a specific file.

Here is the code snippet:

  1. use std::{fs::File, io::Write};
  2. use serde::{Serialize, Deserialize};
  3. #[derive(Debug, Serialize, Deserialize)]
  4. struct Bison {
  5. name: String,
  6. age: u16,
  7. place: String,
  8. phone: u16,
  9. }
  10. pub fn check_bson() {
  11. let mut bisons: Vec<Bison> = Vec::with_capacity(1000);
  12. for i in 1..1001 {
  13. bisons.push(Bison {
  14. name: format!("Name {}", i),
  15. age: i as u16,
  16. place: format!("Place {}", i),
  17. phone: i as u16,
  18. });
  19. }
  20. let mut file = File::create("data.bson").expect("Failed to create file");
  21. let s = bson::to_bson(&bisons).unwrap();
  22. }
英文:

I am trying to convert list of structs and write in a file in BSON format and deserialize back to struct . I am using

  1. bson = { version=&quot;2.6.0&quot; }

crate . I converted my list of structs to Bson , and then tried finding any way to convert the bson to vec[u8] , but didn't find any .

I need to store bson in their binary format only to a specific file.

Here is the code snippet

  1. use std::{fs::File, io::Write};
  2. use serde::{Serialize, Deserialize};
  3. #[derive(Debug,Serialize,Deserialize)]
  4. struct Bison {
  5. name: String,
  6. age: u16,
  7. place: String,
  8. phone: u16,
  9. }
  10. pub fn check_bson() {
  11. let mut bisons: Vec&lt;Bison&gt; = Vec::with_capacity(1000);
  12. for i in 1..1001 {
  13. bisons.push(Bison {
  14. name: format!(&quot;Name {}&quot;, i),
  15. age: i as u16,
  16. place: format!(&quot;Place {}&quot;, i),
  17. phone: i as u16,
  18. });
  19. }
  20. let mut file = File::create(&quot;data.bson&quot;).expect(&quot;Failed to create file&quot;);
  21. let s = bson::to_bson(&amp;bisons).unwrap();
  22. }

答案1

得分: 1

以下是您要翻译的代码部分:

  1. [`BSON`](https://docs.rs/bson/latest/bson/enum.Bson.html) 枚举仅包含文档树。要获取 `Vec&lt;u8&gt;`,您需要实际编码 [`Document`](https://docs.rs/bson/latest/bson/struct.Document.html),可以这样做:
  2. ```rust
  3. use bson::{SerializerOptions, Document};
  4. use serde::{Serialize, Deserialize};
  5. #[derive(Debug,Serialize,Deserialize)]
  6. struct Bison {
  7. name: String,
  8. age: u16,
  9. place: String,
  10. phone: u16,
  11. }
  12. pub fn check_bson() {
  13. let mut bisons: Vec&lt;Bison&gt; = Vec::with_capacity(1000);
  14. for i in 1..1001 {
  15. bisons.push(Bison {
  16. name: format!(&quot;Name {}&quot;, i),
  17. age: i as u16,
  18. place: format!(&quot;Place {}&quot;, i),
  19. phone: i as u16,
  20. });
  21. }
  22. let options = SerializerOptions::builder().human_readable(false).build();
  23. let bson = bson::to_bson_with_options(&amp;bisons, options).unwrap();
  24. println!(&quot;{:?}&quot;, bson);
  25. let mut doc = Document::new();
  26. doc.insert(&quot;array&quot;.to_string(), bson);
  27. let mut buf = Vec::new();
  28. doc.to_writer(&amp;mut buf).unwrap();
  29. std::fs::write(&quot;data.bson&quot;, buf).expect(&quot;Failed to create file&quot;);
  30. }

请注意,我们必须为数组指定一个名称(在这种情况下,我选择了 "array"),因为 Array 本身不是 Document 类型,因此不能用于顶层。

或者,您可以使用 to_vec,但您还必须考虑顶层元素不能是 BSON Array,因此您必须像下面所示包装它:

  1. use serde::{Deserialize, Serialize};
  2. #[derive(Debug, Serialize, Deserialize)]
  3. struct Bison {
  4. name: String,
  5. age: u16,
  6. place: String,
  7. phone: u16,
  8. }
  9. #[derive(Debug, Serialize, Deserialize)]
  10. struct RootElement {
  11. array: Vec&lt;Bison&gt;,
  12. }
  13. pub fn check_bson() {
  14. let mut bisons: Vec&lt;Bison&gt; = Vec::with_capacity(1000);
  15. for i in 1..1001 {
  16. bisons.push(Bison {
  17. name: format!(&quot;Name {}&quot;, i),
  18. age: i as u16,
  19. place: format!(&quot;Place {}&quot;, i),
  20. phone: i as u16,
  21. });
  22. }
  23. // BSON 文档的根元素不能是数组(例如,rust 中的 Vec)。
  24. let data = RootElement {
  25. array: bisons
  26. };
  27. let buf = bson::to_vec(&amp;data).unwrap();
  28. std::fs::write(&quot;data.bson&quot;, buf).expect(&quot;Failed to create file&quot;);
  29. }
  1. <details>
  2. <summary>英文:</summary>
  3. The [`BSON`](https://docs.rs/bson/latest/bson/enum.Bson.html) enum only contains the document tree. In order to get a `Vec&lt;u8&gt;` you will need to actually encode the [`Document`](https://docs.rs/bson/latest/bson/struct.Document.html) which can be done like so:
  4. ```rust
  5. use bson::{SerializerOptions, Document};
  6. use serde::{Serialize, Deserialize};
  7. #[derive(Debug,Serialize,Deserialize)]
  8. struct Bison {
  9. name: String,
  10. age: u16,
  11. place: String,
  12. phone: u16,
  13. }
  14. pub fn check_bson() {
  15. let mut bisons: Vec&lt;Bison&gt; = Vec::with_capacity(1000);
  16. for i in 1..1001 {
  17. bisons.push(Bison {
  18. name: format!(&quot;Name {}&quot;, i),
  19. age: i as u16,
  20. place: format!(&quot;Place {}&quot;, i),
  21. phone: i as u16,
  22. });
  23. }
  24. let options = SerializerOptions::builder().human_readable(false).build();
  25. let bson = bson::to_bson_with_options(&amp;bisons, options).unwrap();
  26. println!(&quot;{:?}&quot;, bson);
  27. let mut doc = Document::new();
  28. doc.insert(&quot;array&quot;.to_string(), bson);
  29. let mut buf = Vec::new();
  30. doc.to_writer(&amp;mut buf).unwrap();
  31. std::fs::write(&quot;data.bson&quot;, buf).expect(&quot;Failed to create file&quot;);
  32. }

Please note, that we had to give a name to the array (in this case I chose "array"), because an Array itself is a non-Document type and can thus not be used at the top level.

Alternatively you can use to_vec, but you will also have to consider that the top-level element can not be a BSON Array, so you will have to wrap it like shown below:

  1. use serde::{Deserialize, Serialize};
  2. #[derive(Debug, Serialize, Deserialize)]
  3. struct Bison {
  4. name: String,
  5. age: u16,
  6. place: String,
  7. phone: u16,
  8. }
  9. #[derive(Debug, Serialize, Deserialize)]
  10. struct RootElement {
  11. array: Vec&lt;Bison&gt;,
  12. }
  13. pub fn check_bson() {
  14. let mut bisons: Vec&lt;Bison&gt; = Vec::with_capacity(1000);
  15. for i in 1..1001 {
  16. bisons.push(Bison {
  17. name: format!(&quot;Name {}&quot;, i),
  18. age: i as u16,
  19. place: format!(&quot;Place {}&quot;, i),
  20. phone: i as u16,
  21. });
  22. }
  23. // The root element of a BSON document can not be an array (e.g. a Vec in rust).
  24. let data = RootElement {
  25. array: bisons
  26. };
  27. let buf = bson::to_vec(&amp;data).unwrap();
  28. std::fs::write(&quot;data.bson&quot;, buf).expect(&quot;Failed to create file&quot;);
  29. }

答案2

得分: 1

以下是您要翻译的内容:

"Your bson 文件的顶层必须是 DocumentVec 遗憾地不能与顶层 bison 使用兼容。它必须是类似于键值映射的东西,例如 HashMapstruct

实现这一目标的最简单方法是将 struct 用作顶层对象。将其转换为二进制的实际调用是 bson::to_vec

  1. use serde::{Deserialize, Serialize};
  2. use std::fs::File;
  3. #[derive(Debug, Serialize, Deserialize)]
  4. struct Bison {
  5. name: String,
  6. age: u16,
  7. place: String,
  8. phone: u16,
  9. }
  10. #[derive(Debug, Serialize, Deserialize)]
  11. struct BisonDoc {
  12. bisons: Vec<Bison>,
  13. }
  14. pub fn main() {
  15. // 写入文件
  16. {
  17. let mut bisons_doc = BisonDoc {
  18. bisons: Vec::with_capacity(3),
  19. };
  20. for i in 1..=3 {
  21. bisons_doc.bisons.push(Bison {
  22. name: format!("Name {}", i),
  23. age: i as u16,
  24. place: format!("Place {}", i),
  25. phone: i as u16,
  26. });
  27. }
  28. let binary_data = bson::to_vec(&bisons_doc).expect("无法创建 bison 数据");
  29. std::fs::write("data.bson", binary_data).expect("无法写入 bson 文件");
  30. }
  31. // 从文件读取
  32. {
  33. let file = File::open("data.bson").expect("无法打开文件");
  34. let bisons: BisonDoc = bson::from_reader(file).expect("读取 bson 数据时出错");
  35. println!("{:#?}", bisons);
  36. }
  37. }
  1. BisonDoc {
  2. bisons: [
  3. Bison {
  4. name: "Name 1",
  5. age: 1,
  6. place: "Place 1",
  7. phone: 1,
  8. },
  9. Bison {
  10. name: "Name 2",
  11. age: 2,
  12. place: "Place 2",
  13. phone: 2,
  14. },
  15. Bison {
  16. name: "Name 3",
  17. age: 3,
  18. place: "Place 3",
  19. phone: 3,
  20. },
  21. ],
  22. }
英文:

The top level of your bson file has to be a Document. A Vec is sadly not compatible with top level bison usage. It has to be something that resembles a key-value mapping, like a HashMap or a struct.

The easiest way to achieve that is to use a struct as the top level object. The actual call to convert it to binary is bson::to_vec:

  1. use serde::{Deserialize, Serialize};
  2. use std::fs::File;
  3. #[derive(Debug, Serialize, Deserialize)]
  4. struct Bison {
  5. name: String,
  6. age: u16,
  7. place: String,
  8. phone: u16,
  9. }
  10. #[derive(Debug, Serialize, Deserialize)]
  11. struct BisonDoc {
  12. bisons: Vec&lt;Bison&gt;,
  13. }
  14. pub fn main() {
  15. // Write to file
  16. {
  17. let mut bisons_doc = BisonDoc {
  18. bisons: Vec::with_capacity(3),
  19. };
  20. for i in 1..=3 {
  21. bisons_doc.bisons.push(Bison {
  22. name: format!(&quot;Name {}&quot;, i),
  23. age: i as u16,
  24. place: format!(&quot;Place {}&quot;, i),
  25. phone: i as u16,
  26. });
  27. }
  28. let binary_data = bson::to_vec(&amp;bisons_doc).expect(&quot;Unable to create bison data&quot;);
  29. std::fs::write(&quot;data.bson&quot;, binary_data).expect(&quot;Failed to write bson file&quot;);
  30. }
  31. // Read from file
  32. {
  33. let file = File::open(&quot;data.bson&quot;).expect(&quot;Unable to open file&quot;);
  34. let bisons: BisonDoc = bson::from_reader(file).expect(&quot;Error while reading bson data&quot;);
  35. println!(&quot;{:#?}&quot;, bisons);
  36. }
  37. }
  1. BisonDoc {
  2. bisons: [
  3. Bison {
  4. name: &quot;Name 1&quot;,
  5. age: 1,
  6. place: &quot;Place 1&quot;,
  7. phone: 1,
  8. },
  9. Bison {
  10. name: &quot;Name 2&quot;,
  11. age: 2,
  12. place: &quot;Place 2&quot;,
  13. phone: 2,
  14. },
  15. Bison {
  16. name: &quot;Name 3&quot;,
  17. age: 3,
  18. place: &quot;Place 3&quot;,
  19. phone: 3,
  20. },
  21. ],
  22. }

huangapple
  • 本文由 发表于 2023年5月13日 15:33:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/76241579.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定