将二进制文件读入结构体

2024-04-24

我正在尝试使用 C# 读取二进制数据。我拥有有关我想要读取的文件中的数据布局的所有信息。我能够“逐块”读取数据,即将前 40 个字节的数据转换为字符串,然后获取接下来的 40 个字节。

由于数据至少有三个略有不同的版本,我想将数据直接读入结构中。感觉比“逐行”阅读要正确得多。

我尝试过以下方法但没有效果:

StructType aStruct;
int count = Marshal.SizeOf(typeof(StructType));
byte[] readBuffer = new byte[count];
BinaryReader reader = new BinaryReader(stream);
readBuffer = reader.ReadBytes(count);
GCHandle handle = GCHandle.Alloc(readBuffer, GCHandleType.Pinned);
aStruct = (StructType) Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(StructType));
handle.Free();

该流是一个打开的 FileStream,我已开始从中读取数据。我得到一个AccessViolationException 使用时Marshal.PtrToStructure.

该流包含的信息比我试图读取的信息多,因为我对文件末尾的数据不感兴趣。

该结构体定义如下:

[StructLayout(LayoutKind.Explicit)]
struct StructType
{
    [FieldOffset(0)]
    public string FileDate;
    [FieldOffset(8)]
    public string FileTime;
    [FieldOffset(16)]
    public int Id1;
    [FieldOffset(20)]
    public string Id2;
}

示例代码对原始代码进行了更改,以使这个问题更短。

如何将二进制数据从文件读取到结构中?


问题是strings 在你的结构中。我发现像 byte/short/int 这样的封送类型不是问题;但是当您需要编组为复杂类型(例如字符串)时,您需要结构显式模仿非托管类型。您可以使用 MarshalAs 属性来执行此操作。

对于您的示例,以下内容应该有效:

[StructLayout(LayoutKind.Explicit)]
struct StructType
{
    [FieldOffset(0)]
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
    public string FileDate;

    [FieldOffset(8)]
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
    public string FileTime;

    [FieldOffset(16)]
    public int Id1;

    [FieldOffset(20)]
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 66)] //Or however long Id2 is.
    public string Id2;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将二进制文件读入结构体 的相关文章

随机推荐