Saturday, August 30, 2008

C++ Read Binary File and convert char * to float

I recently need to write a c++ data reader. The data reader reads a file while is in binary format, and every four byte should be convert into float. I found it very easy to read file, you only need to specify ios::binary when reading. This is a bit different from c#. If you don't define ios::binary, you will get unexpected eof in the middle of the file. With regards to conversion, there are 2 possible ways. First, memcpy which is slow and time consuming. You can also do reinterpret_cast. For example:
char* tmp = new char[sizeof(float)];
float val = 0;
memcpy(tmp, val, sizeof(float));
val = *reinterpret_casttmp
This should give you some idea on how to handle binary file read. The following is the complete example, might not suit your situation though.




#include
#include
#include
#include

using namespace std;
#define interval 400

class Data {
public:
float** data;
Data (const string& file);
};

Data::Data (const string& dataFile) {
ifstream file (dataFile.c_str (),ios_base::in|ios_base::binary);

string line;
int file_length = 0;

file.seekg(0,ios::end);
file_length = file.tellg();
file_length -= 19;
file.seekg(0,ios::beg);

this->data = new float* [file_length/4];
for (int i =0 ; i< file_length/4 ; i++)
{
this->data[i] = new float [3];
}

// Read Header File, Basiclly Ignore It.
char* header = new char[19];
file.read(header,19);

int t = 0;
char* acc = new char[12*interval];
// Read Actual Data;
while (!file.eof())
{
file.read(acc,12*interval);
int read_length = file.gcount()/12;

for (int k = 0 ; k < read_length ; k ++ )
{
for(int j=0;j<3;j++)
{
this->data[t+k][j] = (*reinterpret_cast(acc+12*k+4*j));
}
}
t += read_length;
}
}