【问题标题】:C++ why does the binary file read skips to the endC++为什么读取二进制文件会跳到最后
【发布时间】:2014-09-10 21:05:30
【问题描述】:

我有一个 178 MB FORTRAN 未格式化的二进制文件,我正在使用 C++ 读取该文件并将其存储在特征矩阵中。我已经使用 FORTRAN 和 MATLAB 阅读了该文件,以确认我理解文件中的值。文件中的第一条记录是矩阵的大小。之后,每条记录以 3 个整数开头。这些整数包含数据开始的列和行以及要读取的数字数量。接下来是单精度数字本身。

这是我的代码:

std::ifstream infile("MSFILE", std::ios::in | std::ios::binary);
if(!infile)
{
    std::cout << "Mode shape .f12 file (MSFILE) not found\n";
    exit(1);
}

int r_size1; // size of each record read
int r_size2; // size after reading for comparison

int cols, rows;
infile.read(reinterpret_cast<char *> (&r_size1), 4);
infile.read(reinterpret_cast<char *> (&cols), 4);
infile.read(reinterpret_cast<char *> (&rows), 4);
infile.read(reinterpret_cast<char *> (&r_size2), 4);

if (r_size1 != r_size2)
{
    std::cout << "Error reading MSFILE\n";
    exit(1);
}

MatrixXf data(rows, cols);
data.setZero();

int * vals = new int[3]; // vals holds i_col, i_row and i_word for each record
float * tempf; // pointer to array of floats that holds the data from the file

// Read in the record, and continue through the file
infile.read(reinterpret_cast<char *> (&r_size1), 4);

while (!infile.eof())
{
    infile.read(reinterpret_cast<char *> (vals), 12);
    tempf = new float[vals[2]];
    int buf_size = vals[2] * 4;
    // read the data from the file
    infile.read(reinterpret_cast<char *> (tempf), buf_size);

    // write the float array into the matrix
    data.col(vals[0] - 1) = Map<VectorXf>(tempf, rows);

    infile.read(reinterpret_cast<char *> (&r_size2), 4);

    if (r_size1 != r_size2)
    {
        std::cout << "Error reading MSFILE\n";
        exit(1);
    }

    delete tempf;

    // finish out by reading the next record size...this will also force EOF
    infile.read(reinterpret_cast<char *> (&r_size1), 4);
}

delete vals;

infile.close();

问题是第一次读取float数组时,文件走到了末尾。我在每个infile.read 之后使用infile.tellg() 来跟踪正在发生的事情。一切都移动所需的数量,直到浮点数组的第一个实例。在读取第一个浮点数组之后,文件转到 EOF。 我希望记录包含 26130 个数字。 vals[2] 证实了这一点。 buf_size 是 104520,如预期的那样是 4 * 26130。 tempf 也未完全填充。

【问题讨论】:

  • 构造函数调用应该是std::ifstream infile("MSFILE", std::ios::in|std::ios::binary);(或者你可以跳过ios::in部分,直接使用ios::binary)。我不知道你的电话是如何编译的。你的编译器是什么?
  • @DaleWilson std::ifstream 没有采用三个参数的构造函数。
  • 再试一次:Microsoft 编译器有一个用于 ifstream 的三参数构造函数。第三个参数控制文件共享:msdn.microsoft.com/en-us/library/zek0beca.aspx
  • @Matt,从文件中读取 vals[2] 的值后,你会得到什么?
  • @T.C.: "17.6.5.5/2 实现可以在类中声明其他非虚拟成员函数签名...通过为成员添加成员函数签名函数名。”有问题的扩展名符合要求。

标签: c++ binaryfiles


【解决方案1】:

如果将二进制文件作为文本文件打开,即如果将ifstream的构造函数的第二个参数中的| std::ios::binary去掉,那么read函数可能会遇到一个字节序列,它解释为EOF,但它实际上只是二进制数据的一部分。

至少,这是我过去在微软平台上读取二进制数据时遇到的问题,和你描述的症状(读取的字节数没有预期的多,程序表现得好像到达EOF)是一致的当我的程序在以文本模式读取时从二进制文件中读取“false EOF”时观察到的情况。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    • 2017-10-01
    • 2011-09-03
    • 2016-01-15
    • 1970-01-01
    相关资源
    最近更新 更多