C ++为什么二进制文件读取会跳到最后

时间:2014-09-10 21:05:30

标签: c++ binaryfiles

我有一个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.tellg()之后使用了infile.read来跟踪发生了什么。一切都移动了所需的量,直到浮点数组的第一个实例。在第一个浮点数组读取之后,文件转到EOF。 我希望该记录包含26130个数字。这由vals[2]确认。 buf_size是104520,正如预期的那样是4 * 26130。 tempf也未完全填充。

1 个答案:

答案 0 :(得分:0)

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

至少,这是我在过去读取Microsoft平台上的二进制数据时遇到的问题,以及您描述的症状(没有按预期读取的字节数,程序就好像它已达到EOF)与我在程序在文本模式下阅读时从二进制文件中读取“false EOF”时观察到的内容一致。