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

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

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:

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:

use std::{fs::File, io::Write};

use serde::{Serialize, Deserialize};

#[derive(Debug, Serialize, Deserialize)]
struct Bison {
    name: String,
    age: u16,
    place: String,
    phone: u16,
}

pub fn check_bson() {
    let mut bisons: Vec<Bison> = Vec::with_capacity(1000);
    for i in 1..1001 {
        bisons.push(Bison {
            name: format!("Name {}", i),
            age: i as u16,
            place: format!("Place {}", i),
            phone: i as u16,
        });
    }

    let mut file = File::create("data.bson").expect("Failed to create file");

    let s = bson::to_bson(&bisons).unwrap();
}
英文:

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

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

use std::{fs::File, io::Write};

use serde::{Serialize, Deserialize};

#[derive(Debug,Serialize,Deserialize)]
struct Bison {
    name: String,
    age: u16,
    place: String,
    phone: u16,
}

pub fn check_bson() {
    let mut bisons: Vec&lt;Bison&gt; = Vec::with_capacity(1000);
    for i in 1..1001 {
        bisons.push(Bison {
            name: format!(&quot;Name {}&quot;, i),
            age: i as u16,
            place: format!(&quot;Place {}&quot;, i),
            phone: i as u16,
        });
    }

    let mut file = File::create(&quot;data.bson&quot;).expect(&quot;Failed to create file&quot;);

    let s = bson::to_bson(&amp;bisons).unwrap();
}

答案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),可以这样做:

```rust
use bson::{SerializerOptions, Document};
use serde::{Serialize, Deserialize};

#[derive(Debug,Serialize,Deserialize)]
struct Bison {
    name: String,
    age: u16,
    place: String,
    phone: u16,
}

pub fn check_bson() {
    let mut bisons: Vec&lt;Bison&gt; = Vec::with_capacity(1000);
    for i in 1..1001 {
        bisons.push(Bison {
            name: format!(&quot;Name {}&quot;, i),
            age: i as u16,
            place: format!(&quot;Place {}&quot;, i),
            phone: i as u16,
        });
    }

    let options = SerializerOptions::builder().human_readable(false).build();
    let bson = bson::to_bson_with_options(&amp;bisons, options).unwrap();
    println!(&quot;{:?}&quot;, bson);

    let mut doc = Document::new();
    doc.insert(&quot;array&quot;.to_string(), bson);

    let mut buf = Vec::new();
    doc.to_writer(&amp;mut buf).unwrap();

    std::fs::write(&quot;data.bson&quot;, buf).expect(&quot;Failed to create file&quot;);
}

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

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

use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize)]
struct Bison {
    name: String,
    age: u16,
    place: String,
    phone: u16,
}

#[derive(Debug, Serialize, Deserialize)]
struct RootElement {
    array: Vec&lt;Bison&gt;,
}

pub fn check_bson() {
    let mut bisons: Vec&lt;Bison&gt; = Vec::with_capacity(1000);
    for i in 1..1001 {
        bisons.push(Bison {
            name: format!(&quot;Name {}&quot;, i),
            age: i as u16,
            place: format!(&quot;Place {}&quot;, i),
            phone: i as u16,
        });
    }

    // BSON 文档的根元素不能是数组(例如,rust 中的 Vec)。
    let data = RootElement {
        array: bisons
    };

    let buf = bson::to_vec(&amp;data).unwrap();
    std::fs::write(&quot;data.bson&quot;, buf).expect(&quot;Failed to create file&quot;);
}

<details>
<summary>英文:</summary>

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:

```rust
use bson::{SerializerOptions, Document};
use serde::{Serialize, Deserialize};

#[derive(Debug,Serialize,Deserialize)]
struct Bison {
    name: String,
    age: u16,
    place: String,
    phone: u16,
}

pub fn check_bson() {
    let mut bisons: Vec&lt;Bison&gt; = Vec::with_capacity(1000);
    for i in 1..1001 {
        bisons.push(Bison {
            name: format!(&quot;Name {}&quot;, i),
            age: i as u16,
            place: format!(&quot;Place {}&quot;, i),
            phone: i as u16,
        });
    }

    let options = SerializerOptions::builder().human_readable(false).build();
    let bson = bson::to_bson_with_options(&amp;bisons, options).unwrap();
    println!(&quot;{:?}&quot;, bson);

    let mut doc = Document::new();
    doc.insert(&quot;array&quot;.to_string(), bson);

    let mut buf = Vec::new();
    doc.to_writer(&amp;mut buf).unwrap();

    std::fs::write(&quot;data.bson&quot;, buf).expect(&quot;Failed to create file&quot;);
}

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:

use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize)]
struct Bison {
    name: String,
    age: u16,
    place: String,
    phone: u16,
}

#[derive(Debug, Serialize, Deserialize)]
struct RootElement {
    array: Vec&lt;Bison&gt;,
}

pub fn check_bson() {
    let mut bisons: Vec&lt;Bison&gt; = Vec::with_capacity(1000);
    for i in 1..1001 {
        bisons.push(Bison {
            name: format!(&quot;Name {}&quot;, i),
            age: i as u16,
            place: format!(&quot;Place {}&quot;, i),
            phone: i as u16,
        });
    }

    // The root element of a BSON document can not be an array (e.g. a Vec in rust).
    let data = RootElement {
        array: bisons
    };

    let buf = bson::to_vec(&amp;data).unwrap();
    std::fs::write(&quot;data.bson&quot;, buf).expect(&quot;Failed to create file&quot;);
}

答案2

得分: 1

以下是您要翻译的内容:

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

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

use serde::{Deserialize, Serialize};
use std::fs::File;

#[derive(Debug, Serialize, Deserialize)]
struct Bison {
    name: String,
    age: u16,
    place: String,
    phone: u16,
}

#[derive(Debug, Serialize, Deserialize)]
struct BisonDoc {
    bisons: Vec<Bison>,
}

pub fn main() {
    // 写入文件
    {
        let mut bisons_doc = BisonDoc {
            bisons: Vec::with_capacity(3),
        };
        for i in 1..=3 {
            bisons_doc.bisons.push(Bison {
                name: format!("Name {}", i),
                age: i as u16,
                place: format!("Place {}", i),
                phone: i as u16,
            });
        }

        let binary_data = bson::to_vec(&bisons_doc).expect("无法创建 bison 数据");

        std::fs::write("data.bson", binary_data).expect("无法写入 bson 文件");
    }

    // 从文件读取
    {
        let file = File::open("data.bson").expect("无法打开文件");
        let bisons: BisonDoc = bson::from_reader(file).expect("读取 bson 数据时出错");

        println!("{:#?}", bisons);
    }
}
BisonDoc {
    bisons: [
        Bison {
            name: "Name 1",
            age: 1,
            place: "Place 1",
            phone: 1,
        },
        Bison {
            name: "Name 2",
            age: 2,
            place: "Place 2",
            phone: 2,
        },
        Bison {
            name: "Name 3",
            age: 3,
            place: "Place 3",
            phone: 3,
        },
    ],
}
英文:

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:

use serde::{Deserialize, Serialize};
use std::fs::File;

#[derive(Debug, Serialize, Deserialize)]
struct Bison {
    name: String,
    age: u16,
    place: String,
    phone: u16,
}

#[derive(Debug, Serialize, Deserialize)]
struct BisonDoc {
    bisons: Vec&lt;Bison&gt;,
}

pub fn main() {
    // Write to file
    {
        let mut bisons_doc = BisonDoc {
            bisons: Vec::with_capacity(3),
        };
        for i in 1..=3 {
            bisons_doc.bisons.push(Bison {
                name: format!(&quot;Name {}&quot;, i),
                age: i as u16,
                place: format!(&quot;Place {}&quot;, i),
                phone: i as u16,
            });
        }

        let binary_data = bson::to_vec(&amp;bisons_doc).expect(&quot;Unable to create bison data&quot;);

        std::fs::write(&quot;data.bson&quot;, binary_data).expect(&quot;Failed to write bson file&quot;);
    }

    // Read from file
    {
        let file = File::open(&quot;data.bson&quot;).expect(&quot;Unable to open file&quot;);
        let bisons: BisonDoc = bson::from_reader(file).expect(&quot;Error while reading bson data&quot;);

        println!(&quot;{:#?}&quot;, bisons);
    }
}
BisonDoc {
    bisons: [
        Bison {
            name: &quot;Name 1&quot;,
            age: 1,
            place: &quot;Place 1&quot;,
            phone: 1,
        },
        Bison {
            name: &quot;Name 2&quot;,
            age: 2,
            place: &quot;Place 2&quot;,
            phone: 2,
        },
        Bison {
            name: &quot;Name 3&quot;,
            age: 3,
            place: &quot;Place 3&quot;,
            phone: 3,
        },
    ],
}

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:

确定