3

I have a method which writes a binary file from an int array. (it could be wrong too)

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();
}

I need to now read that binary file back. And preferably have it read it back into another array of unsigned ints without any information loss.

I have something like the following code, but I have no idea on how reading binary files really works, and no idea how to read it into an array of ints.

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();
}

Question:

How to complete the implementation of the function that reads binary files?

Ziezi
  • 6,375
  • 3
  • 39
  • 49
SoundChaos
  • 197
  • 1
  • 6
  • 20
  • consider writing the size of the array first. It would greatly simplify the read code. – alexm Sep 24 '15 at 00:53
  • To add a note here, I cannot use vector. I have a separate class that creates dynamic arrays for me with a given size passed to it, and that class is working properly. I can also determine the size based on the information I send to these arrays. – SoundChaos Sep 24 '15 at 16:53

4 Answers4

4

If you're using C++, use the nice 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;
 }

Writing is just as simple (for this we'll accept an int[] but an std library would be preferable):

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];
}

Here's the same thing but with an std::vector

void bcdEncoder::writeBinaryFile(string fileName, vector<unsigned int> arr)
{
    ofstream f { fileName };
    for (auto&& i : arr)
        f << i;
}
Olipro
  • 3,489
  • 19
  • 25
  • I can't figure out a way to implement a similar read method without vectors, which I am not able to use in this project. – SoundChaos Sep 24 '15 at 16:56
  • Are you completely and utterly banned from using a `vector`, or you're just required to return an `int[]`? – Olipro Sep 24 '15 at 18:58
  • part of the project goal was to apply previously made custom dynamic array class file to a new project. – SoundChaos Sep 25 '15 at 01:56
1

To simplify read operation consider storing size (i.e the number of elements in the array) before the data:

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();
}

The read would look something like:

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
}
alexm
  • 6,854
  • 20
  • 24
  • I'm guessing now that my write is just completely wrong. First off, the &size in the write fails because it says its expecting a char, but overall, when i take in my packedBcd Array (which I know has the correct values in it) the values are not being written into the .bin file in any way that I understand, if at all. – SoundChaos Sep 24 '15 at 16:51
1

Modern alternative using std::array

Here's a code snippet that uses more modern C++ to read a binary file into an 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);
    }

Because you're using an std::array you'll need to know the exact size of the file during compile-time. If you don't know the size of the file ahead of time (or rather, you'll need to know that the file has at least X bytes available), use a std::vector and look at this example here: https://stackoverflow.com/a/36661779/1576548

Raleigh L.
  • 599
  • 2
  • 13
  • 18
0

Thanks for the tips guys, looks like I worked it out!! A major part of my problem was that half the arguments and syntax I added to the methods were not required, and actually messed things up. Here are my working methods.

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;
}

And the read:

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;
}

With the AllocateArray being my class that creates dynamic arrays without vectors somewhat safely with destructors included.

SoundChaos
  • 197
  • 1
  • 6
  • 20