将二进制文件读入类对象

时间:2015-06-03 06:43:18

标签: c++

我希望能够将Music类型的链接列表写入二进制文件,然后再将其读回链接列表。当然,我遇到了这样的问题。据我所知,我的问题是字符串是一个可变长度。由于字符串的大小并不总是相同,因此在阅读时,并不知道要阅读多少。我打算将我的类转换为固定长度的cstrings来解决问题。实际上,我试过,但还有其他一些问题。我的问题是,有没有办法在不彻底改变我的代码的情况下实现我想要的东西?

void ReadBinFile(Node * head, string filename)
{
    Music new_song;
    ifstream bin(filename, ios::in | ios::binary);
    if (bin.is_open())
    {
        while (!bin.eof())
        {
            bin.read(reinterpret_cast<char *>(&new_song), sizeof(Music));
            if (!bin.eof())
            {
                Node * new_node = CreateNode(new_song);
                AppendNode(head, new_node);
            }
        }
        bin.close();
    }
}
void Save(Node * head, string filename)
{
    ofstream bin(filename, ios::out | ios::binary);
    if (bin.is_open())
    {
        Node * traveler = head;
        while (traveler != nullptr)
        {
            bin.write(reinterpret_cast<char *>(&(traveler->song)), sizeof(Music));
            traveler = traveler->next;
        }
        bin.close();
    }
}
Node * CreateNode(Music song)
{
    Node * new_node = new Node;
    new_node->song = song;
    new_node->next = nullptr;

    return new_node;
}
//music.h
class Music
{
    public:
        Music(string name = "", string artist = "");

    private:
        string m_name;
        string m_artist;
};

2 个答案:

答案 0 :(得分:1)

这样做

<table>
    <tbody id="items">

    </tbody>
</table>

如果你看一下你的音乐课

,结局不会很好
bin.read(reinterpret_cast<char *>(&new_song), sizeof(Music));

read只会覆盖不考虑字符串模板实例化的字符串。

为了处理这个重载流媒体操作符class Music { public: Music(string name = "", string artist = ""); private: string m_name; string m_artist; ... >>,以便您可以在代码中读取文件,如下所示:

<<

为此,请在Music类功能之外添加以打包和解压缩实例。

E.g。

...
Music song;
bin >> song;
...

在这些函数中,您将转换为您选择的二进制格式。二进制文件只是以原始方式解释的数据,并且与文本文件没有实际不同,文本文件也是二进制文件,除了假设某种格式,例如二进制文件。可读字符和新行字符。

如果你想以二进制形式存储,你需要找到一种方法来存储足够的信息,以便以后可以检索它。例如如果你存储一个字符串,你可以先存储字符串的长度,然后存储字符串的长度,或者存储字符串,并在结尾处有一个结尾\ 0,这样你就知道在读取字符串时何时停止。

答案 1 :(得分:1)

不幸的是,您使用字符串,它们是自己的类(具有动态分配的长度)。 如果你想写一个全班,它必须是全等大小的,但即便如此,我也不会推荐它。

将读取和写入方法添加到类中,并读取/写入它自己的每个字段。


 作为澄清:你想改变音乐:
class Music { public: Music(string name = "", string artist = ""); void Write(std::string filename); void Read(str::string filename); private: string m_name; string m_artist; };
然后你可以以二进制模式打开文件并写名,然后写艺术家:
size_t len = str.size();
你写字符串的长度
file.write(reinterpret_cast<const char*>(&len), sizeof(len));
然后写出实际的字符串数据:
file.write(str.c_str(), len);


然后你以同样的方式阅读 - &gt;你首先阅读大小,然后阅读许多字符;)
它会重新调整你的代码,但我认为这是正确的方法。