4

我发现了一个特定的 100MB 二进制文件(CarveObj_k5_rgbThreshold10_triangleCameraMatches.bin 在最小示例中),其中谷物无法加载抛出异常“无法从输入流中读取 368 字节!读取 288”

从相同数据构建的相应 900MB XML 文件(在最小示例中为 CarveObj_k5_rgbThreshold10_triangleCameraMatches.xml)正常加载。

XML 文件由

    // {
        // std::ofstream outFile(base + "_triangleCameraMatches.xml");
        // cereal::XMLOutputArchive  oarchive(outFile);
        // oarchive(m_triangleCameraMatches);
    // }

二进制版本由

    // { 
        // std::ofstream outFile(base + "_triangleCameraMatches.bin");
        // cereal::BinaryOutputArchive  oarchive(outFile);
        // oarchive(m_triangleCameraMatches);
    // }

最小示例:https ://www.dropbox.com/sh/fu9e8km0mwbhxvu/AAAfrbqn_9Tnokj4BVXB8miea?dl=0

使用的谷物版本:1.3.0

2017 年

视窗 10

这是一个错误吗?我错过了一些明显的东西吗?同时创建了一个错误报告:https ://github.com/USCiLab/cereal/issues/607

4

1 回答 1

3

在这个特定的实例中,由于构造函数调用ios::binary中缺少标志,所以从 binary.hpp 的第 105 行抛出“无法从输入流读取异常” 。ifstream(这是必需的,否则ifstream会尝试将某些文件内容解释为回车符和换行符。有关更多信息,请参阅此问题。)

因此,从 .bin 文件读取的最小示例中的几行代码应如下所示:

vector<vector<float>> testInBinary;
{
    std::ifstream is("CarveObj_k5_rgbThreshold10_triangleCameraMatches.bin", ios::binary);
    cereal::BinaryInputArchive iarchive(is);
    iarchive(testInBinary);
}

但是,即使在修复此问题后,该特定 .bin 文件中的数据似乎也存在另一个问题,因为当我尝试读取它时,我会抛出一个不同的异常,这似乎是由错误编码的大小值引起的。我不知道这是否是从 Dropbox 复制的人工制品。

Cereal 二进制文件似乎没有基本的 100MB 限制。下面的最小示例创建了一个大约 256MB 的二进制文件并可以正常读取:

#include <iostream>
#include <fstream>
#include <vector>

#include <cereal/types/vector.hpp>
#include <cereal/types/memory.hpp>
#include <cereal/archives/xml.hpp>
#include <cereal/archives/binary.hpp>

using namespace std;

int main(int argc, char* argv[])
{
    vector<vector<double>> test;
    test.resize(32768, vector<double>(1024, -1.2345));
    {
        std::ofstream outFile("test.bin");
        cereal::BinaryOutputArchive oarchive(outFile, ios::binary);
        oarchive(test);
    }

    vector<vector<double>> testInBinary;
    {
        std::ifstream is("test.bin", ios::binary);
        cereal::BinaryInputArchive iarchive(is);
        iarchive(testInBinary);
    }

    return 0;
}

值得注意的是,在您在 Dropbox 上的示例代码中,您在编写 .bin 文件时还缺少构造函数ios::binary上的标志:ofstream

/// Produced by:
// { 
    // std::ofstream outFile(base + "_triangleCameraMatches.bin");
    // cereal::BinaryOutputArchive  oarchive(outFile);
    // oarchive(m_triangleCameraMatches);
// }

设置标志可能值得尝试。希望有些帮助。

于 2020-02-25T15:57:13.827 回答