将二进制文件读入C++整数数组

3

我有一个方法,可以从一个int数组中写入二进制文件。(可能是错误的)

void bcdEncoder::writeBinaryFile(unsigned int packedBcdArray[], int size)
{
    fstream binaryIo;
    binaryIo.open("PridePrejudice.bin", ios::out| ios::binary | ios::trunc);
    binaryIo.seekp(0);
    binaryIo.write((char*)packedBcdArray, size * sizeof(packedBcdArray[0]));
    binaryIo.seekp(0);

    binaryIo.close();
}

我需要现在读取二进制文件。最好是将其读取到另一个无信息损失的unsigned int数组中。
我有类似以下代码的东西,但我不知道如何读取二进制文件,也不知道如何将其读取到一个int数组中。
void bcdEncoder::readBinaryFile(string fileName)
{
    // myArray = my dnynamic int array

    fstream binaryIo;
    binaryIo.open(fileName, ios::in | ios::binary | ios::trunc);

    binaryIo.seekp(0);

    binaryIo.seekg(0);
    binaryIo.read((int*)myArray, size * sizeof(myFile));

    binaryIo.close();
}

问题:

如何完成读取二进制文件的函数实现?


考虑先写出数组的大小,这将极大地简化读取代码。 - alexm
为了在这里添加一条注释,我不能使用向量。我有一个单独的类为我创建动态数组,并传递给它一个给定的大小,该类正常工作。我还可以根据我发送到这些数组的信息确定大小。 - SoundChaos
4个回答

4
如果您正在使用C ++,请使用好用的标准库(std library)。
vector<unsigned int> bcdEncoder::readBinaryFile(string fileName)
{
    vector<unsigned int> ret; //std::list may be preferable for large files
    ifstream in{ fileName };
    unsigned int current;
    while (in.good()) {
        in >> current;
        ret.emplace_back(current);
    }
    return ret;
 }

对于写入操作,只需要一个 int[] 就可以了(虽然最好使用标准库):

void bcdEncoder::writeBinaryFile(string fileName, unsigned int arr[], size_t len)
{
    ofstream f { fileName };
    for (size_t i = 0; i < len; i++)
        f << arr[i];
}

这是同样的东西,但使用了一个std::vector
void bcdEncoder::writeBinaryFile(string fileName, vector<unsigned int> arr)
{
    ofstream f { fileName };
    for (auto&& i : arr)
        f << i;
}

我无法想出一种在没有向量的情况下实现类似读取方法的方式,而在这个项目中我无法使用它们。 - SoundChaos
你是完全被禁止使用vector,还是只需要返回int[] - Olipro
项目目标的一部分是将之前制作的自定义动态数组类文件应用于新项目中。 - SoundChaos

1

使用 std::array 的现代替代方案

以下是一个代码片段,使用更现代的 C++ 将二进制文件读入 std::array 中。


    const int arraySize = 9216; // Hard-coded

    std::array<uint8_t, arraySize> fileArray;

    std::ifstream binaryFile("<my-binary-file>", std::ios::in | std::ios::binary);

    if (binaryFile.is_open()) {
        binaryFile.read(reinterpret_cast<char*>(fileArray.data()), arraySize);
    }

因为你使用的是std::array,所以你需要在编译时知道文件的确切大小。如果你事先不知道文件的大小(或者说,你需要知道文件至少有X个字节可用),请使用std::vector并查看这个例子:https://dev59.com/cGUp5IYBdhLWcg3wo4yd#36661779

1
为了简化读取操作,考虑在数据之前存储size(即数组中元素的数量):
void bcdEncoder::writeBinaryFile(unsigned int packedBcdArray[], int size)
{
   fstream binaryIo;
   binaryIo.open("PridePrejudice.bin", ios::out| ios::binary | ios::trunc);
   binaryIo.seekp(0);
   binaryIo.write(&size, sizeof(size));
   binaryIo.write((char*)packedBcdArray, size * sizeof(packedBcdArray[0]));
   binaryIo.close();
}

这段文字大概是这样的:

阅读将类似于:

void bcdEncoder::readBinaryFile(string fileName)
{
    std::vector<unsigned int> myData;
    int size;

    fstream binaryIo;
    binaryIo.open(fileName, ios::in | ios::binary | ios::trunc);

    binaryIo.read(&size, sizeof(size)); // read the number of elements 

    myData.resize(size); // allocate memory for an array 
    binaryIo.read(myData.data(), size * sizeof(myData.value_type));
    binaryIo.close();

   // todo: do something with myData
}

我现在猜测我的写入代码完全错误。首先,write函数中的&size失败了,因为它期望一个char类型,但是总体来讲,当我输入已打包的BCD数组(我知道其中包含正确的值)时,我无法理解或者没有看到任何方式将这些值写入.bin文件中。 - SoundChaos

0

谢谢大家的建议,看起来我解决了它!我问题的主要部分是我添加到这些方法中的一半参数和语法不是必需的,实际上会使事情变得混乱。这是我的工作方法。

void bcdEncoder::writeBinaryFile(unsigned int packedBcdArray[], int size, string fileName)
{
    ofstream binaryIo;
    binaryIo.open(fileName.substr(0, fileName.length() - 4) + ".bin", ios::binary);
    if (binaryIo.is_open()) {
        binaryIo.write((char*)packedBcdArray, size * sizeof(packedBcdArray[0]));
        binaryIo.close();

        // Send binary file to reader
        readBinaryFile(fileName.substr(0, fileName.length() - 4) + ".bin", size);
    }
    else
        cout << "Error writing bin file..." << endl;
}

然后读取:

void bcdEncoder::readBinaryFile(string fileName, int size)
{
    AllocateArray packedData(size);
    unsigned int *packedArray = packedData.createIntArray();

    ifstream binaryIo;
    binaryIo.open(fileName, ios::binary);
    if (binaryIo.is_open()) {
        binaryIo.read((char*)packedArray, size * sizeof(packedArray[0]));
        binaryIo.close();

        decodeBCD(packedArray, size * 5, fileName);
    }
    else
        cout << "Error reading bin file..." << endl;
}

使用AllocateArray作为我的类来创建动态数组,可以相对安全地使用析构函数,而不需要使用向量。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接