Writing binary with ofstream.

Apr 19, 2011 at 7:47pm
Hello all,

I'm trying to write( serialize? ) a structure to a binary file. I've found many things searching on google but I'm obviously not understanding them as they don't seem to work; or they give me a 1kb file all the time.

The structure looks like this: http://pastebin.com/en6uCWTR

I fill "model" with data and then attempt to write to disk. The current solution looks like this:

1
2
3
4
5
void writeFile(char* filename) {
	ofstream ofs(filename, ios::binary);
	ofs.write(reinterpret_cast<char *>(&model), sizeof(model));
	ofs.close();
}


The above always produces a 1kb file. I have also tried using things like FILE but to no avail.

Any help or advice would be appreciated. Thank you.
Apr 19, 2011 at 8:11pm
You can't save pointers like that. You have to save the data the pointer is pointing to. I would suggest overloading operator <</>> for those classes.
Last edited on Apr 19, 2011 at 8:23pm
Apr 19, 2011 at 8:14pm
You have to be more careful when you write binary data to file.

Given your main structure:
1
2
3
4
5
6
struct fileToDump {
        subset* subsets;

        int iNumSubsets;
        int iVersionID;
};
There are only two concrete things in there: iNumSubsets and iVersionID, both integers. The other element is a pointer to another structure, not the structure itself. Writing a pointer to file is meaningless. You want to write the data that the pointer addresses. Hence, your write routine needs to be a bit more sophistocated.

Here is a simple example to help:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
struct point
  {
  int x, y;
  };

struct points
  {
  unsigned count;
  point*   data;
  };

void writePointToFile( std::ofstream& f, const point& p )
  {
  f.write( static_cast <char*> ( &p ), sizeof( point ) );
  }

bool writePointsToFile( const char* filename, const points& pts )
  {
  std::ofstream f( filename, ios::binary );
  f.write( static_cast <char*> ( &(pts.count) ), sizeof( unsigned ) );
  for (unsigned n = 0; n < pts.count; n++)
    {
    writePointToFile( f, pts.data[ n ] );
    }
  return f.good();
  }

Other considerations:
- endianness
- data sizes (is an int two bytes or four? or eight?)
- floating point number format (may vary depending on hardware)
- you list the number of things in your structures after the things being numbered.
   This is a nightmarish thing to. Change it around and put the number of things first
   (like I did in the example above).

I have tried to use syntax that is easy to follow above, but it is possible to do things differently.

Hope this helps.
Apr 19, 2011 at 8:15pm
@firedraco
stream operators >> and << are not meant for binary I/O
@EmilyRossi
You can use Boost serialization library to serialize your structure for you:
http://www.boost.org/doc/libs/1_46_1/libs/serialization/doc/index.html
Apr 19, 2011 at 8:23pm
^Ah, d'oh. I apparently ignored the "binary" part. XD
Apr 19, 2011 at 8:32pm
Thanks for your responses. I think I'm going to go the boost route as I am already using it for other things. Though I will still look into the things you listed Duoas, never hurts to learn new things.

I also have to say, when googling firedraco's suggestion, I "lol'd" when reading wikipedia as it refers to operator overloading as "operator ad-hoc polymorphism" :). I'd never heard that before.

Thanks again. ;)
Topic archived. No new replies allowed.