-
Object serialization
I'm considering saving game items data in a binary file, instead of an ascii file. Just need to clarify one detail before complicating my code unnecessarily.
From what I've been reading about binary mode fstreams, it is still possible to have different size objects written and read as long as I separate them with some form of delimiter between data members?
Or is it best I develop my Item class hierarchy with fixed lenght members? Thus replacing std::strings with const char*, std:: vectors with arrays, and such. This option seems too extravagant.
What is the method commonly used?
-
If your class has only fixed-length character arrays, or integers or fixed-length arrays of structures, and no pointers, then this is the easiest, simplest and fastest way to read/write to binary files. However ..... the drawback is that you can't change the size of the class, such as add or remove data objects without tossing the data file into the bit bin.
If the class has pointers then there is no point in changing from std::string to char* because the class cannot be written in one big swoop anyway. One way I have used in the past is to write to a text file (instead of binary file) with each object preceeded by the object name. For example, suppose the class contains three strings -- name, street and city. The file might look something like this:
Code:
name=john smith
street=111 anywhere st
city=yourdown, usa
now if you want to add another object to the file, you can still use the original file but just add the new data. Reading the data back is a snap too even if the size of the class changes.
-
The only benefit I can see to using binary is if your classes are of fixed size, so I would just use text mode. What benefit are you attempting to achieve by using binary?
-
Data hidding mostly, albeit I could probably simplify the matter with some encryption method.
EDIT:Reading would also be considerably faster if it was in binary format
-
How would binary mode hide your data?
-
err... is this a quiz? :)
data in binary mode is read and written in bytes. Without the proper type to give it a meaning, data is mostly "hidden". Also in binary mode data has no structure. It's simply a sequence of bytes.
-
Characters are just bytes, so your character data will be there to see easily. If you write out in ASCII, you can put the data in any order you want and hide the meaning as well, potentially with less work than it would take to make all your data a fixed size. Simply comparing the data file before and after a change would probably give away how the data is stored if somebody wanted to look whether you used binary or ASCII output.
-
Most of the data would actually be numeric. data members like weight, damage, size, or other numbers mapping to spell effects, and such... I don't have a precise notion of exactly what my CItem base hierarchy will look like in the end. But guaranteed that the most I could expect of string like data members would be a few things like item name and description.
I'm basically curious Daved, since binary mode seems to be a standard way of storing game data by many games.
It is obvious different types of objects have different properties (weapons and armor for instance) and even if they hadn't, the name and description fields would alone mean instances of the same object would have different sizes.
Surely I can save everything in text format as you and Ancient Dragon suggested. But I would like to consider the possibility of a binary format more out of curiosity than of necessity. At least understand how object serialization is done when instances of a given object are obviously expected to have different sizes. The only thing that occurred to me was to either set fixed size data members (with all the wasted memory implications this may mean) or have delimiters set on the file between data members(and I'm not even sure if this one would be feasible). Both seem crude. Certainly things are done in some better way.
But I'll move on to text format and maybe research this later when the need trully arises.
-
Another possibility is to output the size before outputting the data. In that way you could keep the string or other variable length member data, but still be able to write that data in binary mode and read it in by reading in the size first. It wouldn't be a simple conversion, but shouldn't be too much harder than writing in ASCII.
I would imagine that commercial games take serious steps to prevent people from figuring out their file formats so that the integrity of the games cannot be so easily compromised. Whether you want to go to such lengths for your application is up to you.
>> But I'll move on to text format and maybe research this later when the need trully arises.
I think this is a wise move. Just make sure your code encapsulates the data serialization well enough that you can change it in the future if you choose to do so. Using text mode now will also help immensely in your debugging.
-
For a binary 'chunk' type file you would need this:
File header
Chunk header
Raw data
Chunk header
Raw data
...
...ad nauseum
This is very simple to create. EA games start with the chunk format using RIFF. Whatever format you use, just make sure it works. I tend to stay away from text files for games and apps because in most of my apps the files I read in - directly control the instantiation of objects. Last thing I need is some moron poking around in the text file and messing it all up. At least with a binary file even though some of it may be legible - it will ward off a lot of wannabe's when they see al the gobbly gook come up on their screen.
-
Ah. Excellent. The size of the of the data chunk in a fixed size format would certainly do as a much cleaner solution. Thanks Daved. And RIFF, as suggested by Bubba builds on this notion.
I placed a note around the RIFF file format (a bookmark to wiki). For now I'll stick to a plain ascii file and try to encapsulate object instantiation the best I can, so that I come to it later and possibly change to binary mode.
Thanks you two.