0

code looks like this:

struct Dog {
  string name;
  unsigned int age;
};

int main()
{
    Dog d = {.age = 3, .name = "Lion"};
    FILE *fp = fopen("dog.txt", "wb");
    fwrite(&d, sizeof(d), 1, fp);   //write d into dog.txt
}

My problem is what's the point of write a data object or structure into a binary file? I assume it is for making the data generated in a running program persistent, right? If yes, then how can I get the data back? Using fread?

This makes me think of database-like stuff, dose database write data into disk the same way?

Alcott
  • 17,905
  • 32
  • 116
  • 173

4 Answers4

2

Writing data in binary is extremely useful and much faster then reading/writing in text, take for instance video games (Although not every video game does this), when the game is saved all of the nescessary structures/classes and other data are written into a save file in binary.

It is just one use for using binary, but the major reason for doing this is speed.

And to read the data back, you will need to know the format that you saved it in, for instance as a simple example, if I saved an integer, char array of n size, and a boolean, I would need to read the binary file in as an integer, char array of n size, and a boolean. Otherwise the data is read improperly and will not be very useful at all

user1294021
  • 322
  • 3
  • 11
  • 1
    Also I would consider using the C++ fstream class as it is much easier to use and saves alot of headaches. – user1294021 Aug 16 '12 at 03:16
  • How is fstream useful if you are using C? – Adrian Cornish Aug 16 '12 at 03:17
  • 1
    He tagged it C, but there is a string type which makes it look like C++. – Scooter Aug 16 '12 at 03:22
  • 1
    That's why I specified C++...right? There is no reason NOT to use C++ as well as C, C may not be deprecated but it has been expanded upon greatly and every compiler I can think of allows for the use of both. The real question is, why hold someone back from using a highly optimized and widely used class that is almost definitely available to the OP – user1294021 Aug 16 '12 at 03:23
  • Why it is faster than using text mode? – Alcott Aug 16 '12 at 03:41
  • it is faster because avoid type conversion and use less bytes. – olivecoder Aug 16 '12 at 10:17
  • Binary is always faster then reading text, as well as if you are storing your integers as a text string, then you need to convert that string to an integer which is really slow, if you use binary you can directly read the binary into an integer. – user1294021 Aug 16 '12 at 21:00
2

You can do it but you will have a lot of issues to care about:

  • structure types: all your data needs really be into struct or you can just writing a pointer to some other place.
  • structure changes: if you need change your structure you will need write a converter to read old struct and write the new.
  • language interoperability: will be hard to access the data using other language

It was a common practice in the early days before relational databases popularization. You can make index files pointing to a record number.

However nowadays I will advice you to make serialization and write strings instead binaries.

NOTE: if string is something like char[40] your code maybe will survive... but if your question is about C++ and string is a class then kill you child before it grows up! The string object characters are not into your struct but in the heap.

olivecoder
  • 2,858
  • 23
  • 22
  • Why write strings instead of binaries? – Alcott Aug 16 '12 at 03:54
  • Writing strings in a not fixed size format (csv,Jason,XML...) reverts all claims above in your favor. The thing about c++ string type will be OK, will be easier to add new attributes and to integrate with any other language. – olivecoder Aug 16 '12 at 10:12
1

Be careful. The type of field 'name' in your structure is 'string'. This class contains data allocated dynamically. So writing 'string' data into file this way only pointers will be writed, not data itself.

Danil Onishchenko
  • 2,030
  • 11
  • 19
  • correct, if it is the C++ string class you are using then you will need to use string.c_str() to retrieve the char string, and use string.size() * sizeof(char) for the size of the string. – user1294021 Aug 16 '12 at 03:27
  • Then how should I write the `name`'s data into the file? `fwrite(name.c_str(), name.size(), 1, fp)`?\ – Alcott Aug 16 '12 at 03:43
  • In that case you also have to write string length into file. Instead you cant read it correctly. Or you can write '\0' to the end of string. – Danil Onishchenko Aug 16 '12 at 04:04
  • Exactly, either a null termination or a header containing the size is needed. – user1294021 Aug 16 '12 at 21:01
0

The C++ Middleware Writer supports binary serialization to/from files.

From a marshalling perspective the "unsigned int age" member of your struct is a potential problem. I'd consider changing the type to uint32_t.

Jake
  • 1