c ++编写和读取二进制文件的对象

时间:2014-10-04 21:42:47

标签: c++ binaryfiles

我正在尝试读取一个数组对象(Array是我使用读取和写入函数从二进制文件读取和写入的类。到目前为止,写入函数有效,但它无法正确读取文件出于某种原因。这是写函数:

void writeToBinFile(const char* path) const
    {
        ofstream ofs(path, ios_base::out | ios_base::app | ios_base::binary);
        if (ofs.is_open())
        {
            ostringstream oss;
            for (unsigned int i = 0; i < m_size; i++)
            {
                oss << ' ';
                oss << m_data[i];
            }
            ofs.write(oss.str().c_str(), oss.str().size());
        }
    }

这是读取功能:

void readFromBinFile(const char* path)
    {
        ifstream ifs(path, ios_base::in | ios_base::binary || ios_base::ate);
        if (ifs.is_open())
        {
            stringstream ss;
            int charCount = 0, spaceCount = 0;
            ifs.unget();
            while (spaceCount != m_size)
            {
                charCount++;
                if (ifs.peek() == ' ')
                {
                    spaceCount++;
                }
                ifs.unget();
            }
            ifs.get();
            char* ch = new char[sizeof(char) * charCount];
            ifs.read(ch, sizeof(char) * charCount);
            ss << ch;
            delete[] ch;
            for (unsigned int i = 0; i < m_size; i++)
            {
                ss >> m_data[i];
                m_elementCount++;
            }
        }
    }

这些是类字段:

T* m_data;
unsigned int m_size;
unsigned int m_elementCount;

我正在使用以下代码编写然后读取(1次执行以读取另一个用于写入):

Array<int> arr3(5);
    //arr3[0] = 38;
    //arr3[1] = 22;
    //arr3[2] = 55;
    //arr3[3] = 7;
    //arr3[4] = 94;
    //arr3.writeToBinFile("binfile.bin");
    arr3.readFromBinFile("binfile.bin");
    for (unsigned int i = 0; i < arr3.elementCount(); i++)
    {
        cout << "arr3[" << i << "] = " << arr3[i] << endl;
    }

问题现在在readFromBinFile函数中,它陷入无限循环,peek()由于某种原因返回-1,我无法理解为什么。 另请注意,我正在使用空格写入二进制文件,以便在每个元素之间形成一个屏障,因此我知道要区分数组中的对象以及写入开始时的空格,以便在之前存储的二进制数据之间形成障碍。文件到数组二进制数据。

1 个答案:

答案 0 :(得分:1)

在我看来,主要问题是您以可变大小的文本形式编写固定大小的二进制数据。如果你坚持使用纯二进制形式,它可能会简单得多。

不是写入字符串流然后将该输出写入实际文件,而是直接将二进制数据写入文件:

ofs.write(reinterpret_cast<char*>(m_data), sizeof(m_data[0]) * m_size);

然后在阅读数据时做类似的事情。


为了实现这一点,您当然需要在写入实际数据之前先保存数组/向量中的条目数。

因此实际的写入功能可以像

一样简单
void writeToBinFile(const char* path) const
{
    ofstream ofs(path, ios_base::out | ios_base::binary);
    if (ofs)
    {
        ofs.write(reinterpret_cast<const char*>(&m_size), sizeof(m_size));
        ofs.write(reinterpret_cast<const char*>(&m_data[0]), sizeof(m_data[0]) * m_size);
    }
}

读取功能

void readFromBinFile(const char* path)
{
    ifstream ifs(path, ios_base::in | ios_base::binary);
    if (ifs)
    {
        // Read the size
        ifs.read(reinterpret_cast<char*>(&m_size), sizeof(m_size));

        // Read all the data
        ifs.read(reinterpret_cast<char*>(&m_data[0]), sizeof(m_data[0]) * m_size);
    }
}

根据您定义m_data的方式,您可能需要在读取实际数据之前为其分配内存。


哦,如果你想在数组的末尾附加数据(但是为什么你会在你显示的当前代码中,你重写整个数组)你在开头写了大小,寻找到最后,然后写下新数据。