如果您不需要丰富的序列化 - 如果您只想将结构写入字节数组,请考虑 Marshal 类。
例如,考虑一个 C# 中的 tar 应用程序。 tar 格式基于 512 字节的块,系列中的第一个块具有规则的结构。理想情况下,该应用只想blitt 将磁盘文件中的数据直接放入一个结构中。 Marshal.PtrToStructure 方法可以做到这一点。这是结构。
[StructLayout(LayoutKind.Sequential, Size=512)]
internal struct HeaderBlock
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
public byte[] name; // name of file.
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] mode; // file mode
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] uid; // owner user ID
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] gid; // owner group ID
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
public byte[] size; // length of file in bytes
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
public byte[] mtime; // modify time of file
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] chksum; // checksum for header
// ... more like that... up to 512 bytes.
然后这是一个执行 blitting 的泛型类。
internal class RawSerializer<T>
{
public T RawDeserialize( byte[] rawData )
{
return RawDeserialize( rawData , 0 );
}
public T RawDeserialize( byte[] rawData , int position )
{
int rawsize = Marshal.SizeOf( typeof(T) );
if( rawsize > rawData.Length )
return default(T);
IntPtr buffer = Marshal.AllocHGlobal( rawsize );
Marshal.Copy( rawData, position, buffer, rawsize );
T obj = (T) Marshal.PtrToStructure( buffer, typeof(T) );
Marshal.FreeHGlobal( buffer );
return obj;
}
public byte[] RawSerialize( T item )
{
int rawSize = Marshal.SizeOf( typeof(T) );
IntPtr buffer = Marshal.AllocHGlobal( rawSize );
Marshal.StructureToPtr( item, buffer, false );
byte[] rawData = new byte[ rawSize ];
Marshal.Copy( buffer, rawData, 0, rawSize );
Marshal.FreeHGlobal( buffer );
return rawData;
}
}
您可以将该类与 any 结构一起使用。您必须使用 LayoutKind.Sequential 并将自己限制为可 blittable 类型(基本上是相同的基元和数组)才能使用这种方法。就代码、性能和内存而言,它快速高效,但在使用方式上受到了一些限制。
一旦你有了字节数组,你可以通过 NetworkStream 等传输它,然后在另一端使用相同的类进行反序列化。