對於不是可串行化且僅包含基本類型的非常簡單的結構體,這可行。我用它來解析具有已知格式的文件。清除錯誤檢查已刪除。
using System;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
namespace FontUtil
{
public static class Reader
{
public static T Read<T>(BinaryReader reader, bool fileIsLittleEndian = false)
{
Type type = typeof(T);
int size = Marshal.SizeOf(type);
byte[] buffer = new byte[size];
reader.Read(buffer, 0, size);
if (BitConverter.IsLittleEndian != fileIsLittleEndian)
{
FieldInfo[] fields = type.GetFields();
foreach (FieldInfo field in fields)
{
int offset = (int)Marshal.OffsetOf(type, field.Name);
int fieldSize = Marshal.SizeOf(field.FieldType);
for (int b = offset, t = fieldSize + b - 1; b < t; ++b, --t)
{
byte temp = buffer[t];
buffer[t] = buffer[b];
buffer[b] = temp;
}
}
}
GCHandle h = GCHandle.Alloc(buffer, GCHandleType.Pinned);
T obj = (T)Marshal.PtrToStructure(h.AddrOfPinnedObject(), type);
h.Free();
return obj;
}
}
}
的Structs需要聲明是這樣的(並且不能包含數組,我認爲,並沒有說出來 - 字節序交換可能會感到困惑)。
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct NameRecord
{
public UInt16 uPlatformID;
public UInt16 uEncodingID;
public UInt16 uLanguageID;
public UInt16 uNameID;
public UInt16 uStringLength;
public UInt16 uStringOffset; //from start of storage area
}
'MemoryStream'? – Nate
你應該考慮讓你的類型可序列化。如果這是你感興趣的東西,我會提供一個樣本。有關二進制序列化,請參閱「BinaryFormatter」。 –
@Nate,謝謝,它似乎使用'MemoryStream'是一個好主意! @GlennFerrieLive,我以前從來沒有使用過'BinaryFormatter',但是通過一些例子來判斷它看起來像是「爲我鑄造一個結構體」。即使是一個小樣本,我也會很感激。謝謝! – Joulukuusi