Click to See Complete Forum and Search --> : saving a structure as binary
stevendo
August 29th, 2008, 10:09 PM
so i was wondering how exactly do i go about saving a structure a a bionary format
say in c i have
struct mystructre {
int number;
char mystring [50];
};
...save the structure as binary...
how would i do this in C# with a string as the char array?
darwen
August 30th, 2008, 01:47 AM
Hello. Please use code tags - see link in my signature.
Try this :
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
struct Example
{
public int number;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 50)]
public string message;
}
You can test this by doing :
Example example = new Example();
example.number = 100;
example.message = "hello";
byte[] data = new byte[Marshal.SizeOf(example)];
GCHandle dataPtr = GCHandle.Alloc(data, GCHandleType.Pinned);
Marshal.StructureToPtr(example, dataPtr.AddrOfPinnedObject(), false);
Example newExample = (Example)Marshal.PtrToStructure(dataPtr.AddrOfPinnedObject(), typeof(Example));
dataPtr.Free();
Console.WriteLine(string.Format("{0} {1}", newExample.number, newExample.message));
You can then use a BinaryWriter with a MemoryStream to write the structure to binary.
Darwen.
stevendo
August 30th, 2008, 11:06 AM
ok i understand all of this but do i write dataPtr or newexample to the file using the binary writer? is newExample simple showing how to read that data back in?
darwen
August 30th, 2008, 01:44 PM
If you looked at the members on BinaryWriter this should have been obvious, but anyway here's some more code
I write out the size of the byte array containing the struct before writing out the struct data, so that when reading back in I know how many bytes to read.
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
struct Example
{
public int number;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 50)]
public string message;
}
class Program
{
static void SaveExample(Example example, string filename)
{
byte[] data = new byte[Marshal.SizeOf(example)];
// save the structure's data to the byte [] array 'data'
GCHandle dataPtr = GCHandle.Alloc(data, GCHandleType.Pinned);
Marshal.StructureToPtr(example, dataPtr.AddrOfPinnedObject(), false);
dataPtr.Free();
// save to a file
using (FileStream stream = new FileStream(filename, FileMode.Create))
{
BinaryWriter writer = new BinaryWriter(stream);
writer.Write(data.Length); // write the length of the data first
writer.Write(data); // write the struct data
}
}
static Example LoadExample(string filename)
{
using (FileStream stream = new FileStream(filename, FileMode.Open))
{
BinaryReader reader = new BinaryReader(stream);
// get the length of the structure's data
int dataLength = reader.ReadInt32();
// read the structure's data
byte[] data = reader.ReadBytes(dataLength);
GCHandle dataPtr = GCHandle.Alloc(data, GCHandleType.Pinned);
Example example = (Example)Marshal.PtrToStructure(dataPtr.AddrOfPinnedObject(), typeof(Example));
dataPtr.Free();
return example;
}
}
static void Main(string[] args)
{
Example example = new Example();
example.number = 100;
example.message = "hello";
string filename = @"c:\test.dat";
SaveExample(example, filename);
Example newExample = LoadExample(filename);
Console.WriteLine("{0} {1}", newExample.number, newExample.message);
}
}
Talikag
August 30th, 2008, 03:04 PM
Isn't it possible to serialize a struct?
You can easily convert from bytes to binary...
darwen
August 30th, 2008, 04:25 PM
Isn't it possible to serialize a struct?
You can easily convert from bytes to binary...
If you're talking about the BinaryFormatter as detailed here ('http://msdn.microsoft.com/en-us/library/72hyey7b(VS.71).aspx') then this doesn't just put the struct data into the stream : it saves a considerable amount of extra information such as type, assembly credentials etc etc.
I'm presuming stevendo needs to save the same way as C++ would save the structure.
Darwen.
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.