0

i have some Problem reading a 2D Vector from a binary File:

For Example:

My Binary File is structured like this :

243524
764756
746384

Now i want to create a 2D Vector which looks exactly like the bin File.

What i've done so Far:

I created a 1D Vector which contains all Elements. Then i created a Loop and filled the 2D Vector.

My Problem ist that i have a huge .bin File and the for loop cost a lot of Time. is there a possibility to get the 2DVector faster ?

My Code :

ifstream file("C:\\XXX.bin", ios::in | ios::binary | ios::ate);
char * buffer;
long size;
file.seekg(0, std::ios::end); 
size = file.tellg();  

buffer = new char[size];
file.read(buffer, size);
file.close();   


double* double_values = (double*)buffer;//reinterpret as doubles
vector<double> buffer2(double_values, double_values + (size / sizeof(double)));

//cout << "Filling matrix with test numbers.";
int h = 0;
for (int i = 0; i < (size / sizeof(double)) / row; i++)
{
    vector<double> temp;
    for (int j = 0; j < row; j++)
    {
        if (h<size / sizeof(double))
        {
            temp.push_back(buffer2[h]);
            h++;
        }

    }

    bin_file.push_back(temp);
}

Hope that sb can Help me :)

3
  • 2
    My advice would be to use a single dimension vector, make it a member of a class, and use that class to fake the vector has two dimensions by overloading the operator(). That should help to speed up the reading as you can read the whole file into a single vector. Commented Mar 1, 2017 at 20:45
  • Example of what @NathanOliver writes about (sans vector, but easily modified to use vector). Commented Mar 1, 2017 at 20:47
  • Sry i don't get it..:( What i've done now is that i stored all elements of the .bin File in a Vector called Elements. This Vector is part of an class with the Name Test. And How do i create now the 2dVector with overloading the operator() ? Do you have maybe a code example ? Sorry for my stupid Question but i never used overloading operators :/ Commented Mar 1, 2017 at 21:08

1 Answer 1

1

Suggestion: eliminate the copying by reading directly into the vector with std::vector::data

ifstream file("C:\\XXX.bin", ios::in | ios::binary | ios::ate);
char * buffer;
long size;
file.seekg(0, std::ios::end); 
size = file.tellg();  
//allocate a properly sized vector of doubles. Probably should test that size 
// is evenly divisible
vector<double> buffer(size/sizeof(double));
// read into the vector of doubles by lying and saying it's an array of char 
file.read((char*)buffer.data(), size);
file.close();   

Note that the vector is 1D. Access to this vector requires a bit of math. You could

buffer[map2dto1d(row, column)];

where

size_t map2dto1d(size_t row, size_t column)
{
    return row * numberColumns + column;
}

but you are better off wrapping the vector in a class that stores the row and column information along with a properly sized vector and forces the user to index correctly.

Something like this:

class Matrix
{
private:
    size_t rows, columns;
    std::vector<double> matrix;
public:
    // zero initialized matrix of row by column
    Matrix(size_t numrows, size_t numcols):
        rows(numrows), columns(numcols), matrix(rows * columns)
    {
         // can place file reading logic here, but make sure the file matches 
         // numrows * numcols when reading and throw an exception if it doesn't
    }

    // matrix of row by column using provided in vector. in will be 
    // consumed by this constructor 
    // make sure in is big enough to support rows * columns
    Matrix(size_t numrows, size_t numcols, std::vector<double> && in):
        rows(numrows), columns(numcols), matrix(std::move(in))
    {

    }

    double & operator()(size_t row, size_t column)
    {
        // check bounds here if you care
        return matrix[row * columns + column];
    }

    double operator()(size_t row, size_t column) const
    {
        // check bounds here if you care
        return matrix[row * columns + column];
    }

    size_t getRows() const
    {
        return rows;
    }
    size_t getColumns() const
    {
        return columns;
    }

};
// convenience function for printing matrix
std::ostream & operator<<(std::ostream &  out, const Matrix & in)
{
    for (int i = 0; i < in.getRows(); i++)
    {
        for (int j = 0; j < in.getColumns(); j++)
        {
            out << in(i,j) << ' ';
        }
        out << std::endl;
    }

    return out;
}
Sign up to request clarification or add additional context in comments.

2 Comments

THX for your Help i really appreciate it. But i have another Question. With this Method i am creating a vector and pretending that it is a 2d Vector.... Because my Problem is that the main purpose of my code (end result) should be 6 different vectors. Every Vector is containing one column of the matrix from the binary File. and i'm not sure if i'll get this with that method.. Do you maybe have also an idea how i could realize that... sorry for circumstances :/
Maybe i explained wrong my Intention in the Question.. i created a new Question with better explanation. i didn't deleted this Question because the answer wasa good explanation and maybe someone else will need it

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.