I've got a binary file that contains several types of data structures.
Each of the structures are fixed length and about the first half of each structure is identical including an identifying int value that declares the type of the structure. I'm thinking my initial approach is to read enough bytes to get to the identifying int and determine the type of structure and then read the remaining bytes (for that type of structure) and marshal all the bytes into a structure. Next read in the next identifying int and so on.
I've searched on google and found some articles but what I found is pretty dated. I believe the latest article is from 2005.
Any comments about my approach or suggestions would be appreciated. Sample code would be even better.
Re: Reading a binary file into multiple structures
I tried saving a struct into binary and reading it back using the Marsal object like you mentioned. I assume that this binary data comes from a C++ program and you're trying to load it in C#? The code I got here works but it only loads one struct per file, but i'm sure you can modify it to do multiple files. You just need to know what order the structs are in and then just read the required length and load that into the buffer.
Just modify the deserialize function to take a stream input instead of a filename. Them make another class to load the file, read the required bytes for each struct into a stream and deserialize that stream. Do that for each struct in the file and you're good. Sounds like you already know what to do there so i just added the code to convert a struct in C# into binary format and back.
Re: Reading a binary file into multiple structures
That's a pretty standard thing to do and you described it perfectly. In psuedo code it's like:
Code:
Stream stream = GetDataStream ();
while (stream.NotAtEnd ()) {
int type = stream.ReadInt ();
switch (type) {
case 1: return WhateverMessage.Decode (stream);
case 2: return OtherMessage.Decode (stream);
}
}
...
...
public class WhateverMessage : IMessage
{
public int Width { get; set; }
public int Height { get; set; }
public static IMessage Decode (Stream stream)
{
WhateverMessage m = new WhateverMessage ();
m.Width = stream.ReadInt ();
m.Height = stream.ReadInt ();
return m;
}
}
That's the most simplistic approach. If your message types are fixed and will not change it'll be fine. If you require being able to add/remove message types at runtime, use a factory pattern to register/unregister 'MessageDecoders' which will read the stream and return the correct message.
NOTE: My code snippets are just snippets. They demonstrate an idea which can be adapted by you to solve your problem. They are not 100% complete and fully functional solutions equipped with error handling.
Re: Reading a binary file into multiple structures
Mutant, what about when the indentifying type isn't at the beginning of the structure?
Code:
public class SomeMessageA : IMessage
{
public int Width { get; set; }
public int Height { get; set; }
public int Type { get; set; }
// more fields
}
public class SomeMessageB : IMessage
{
public int Width { get; set; }
public int Height { get; set; }
public int Type { get; set; }
// more fields
// and even more fields
}
How do I read ahead to access the type variable without advancing the current position?
Re: Reading a binary file into multiple structures
You can always set the position back 4 bytes if you're reading an int value to get the type. You have access to both get and set methods of the Stream.Position property.
Re: Reading a binary file into multiple structures
Another approach would be to read the initial bytes into a MemoryStream. Then read the byte which indicates which type it is, record it, then push it and the remaining required bytes into the MemoryStream and pass that to your Decode function.
NOTE: My code snippets are just snippets. They demonstrate an idea which can be adapted by you to solve your problem. They are not 100% complete and fully functional solutions equipped with error handling.
* The Best Reasons to Target Windows 8
Learn some of the best reasons why you should seriously consider bringing your Android mobile development expertise to bear on the Windows 8 platform.