将文件中间的结构提取到我的结构中,而不是逐字节访问文件字节并编写其值 [英] Extracting structs in the middle of a file into my structures other than accessing the file byte for byte and compose their value

查看:51
本文介绍了将文件中间的结构提取到我的结构中,而不是逐字节访问文件字节并编写其值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

二进制文件具有以下布局:

A binary file has the following layout:

[FileIdentifier][HeaderStruct][ItemStruct]*[MuchBinaryData]

[HeaderStruct]包含一个Count字段,指示跟随多少[ItemStruct]条记录.如果不分析这些数据,我将无法访问[MuchBinaryData].

The [HeaderStruct] contains a Count field, indicating how many [ItemStruct] records follow. Without analyzing this data, I can't access [MuchBinaryData].

定长结构如下:

Public Structure HeaderStruct
    Public MajorVersion As Integer
    Public MinorVersion As Integer
    Public Count As Integer         'Number of contained ItemStruct.
End Structure

Public Structure ItemStruct
    Public ItemType As Type              
    Public Length As Long 
    ...          
End Structure

检索[FileIdentifier]字段很简单,它只有6个字节.

Retrieving the [FileIdentifier] field is trivial, it's just a field of 6 bytes.

Public Sub New(sFileName As String)
    Dim abFileID(0 To FILEIDENTIFIER.Length - 1) As Byte
    If File.Exists(gsFileName) Then
        Using oFS = File.Open(sFileName, FileMode.Open, FileAccess.Read)
            oFS.Read(abFileID, 0, abFileID.Length)
            ...
        End Using
    End If
End Sub

所以我的问题是:如何检索这些(可变数量)结构以及结构?

So my question is: how can I retrieve these (variable number) of structures as, well, structures?

我真的需要访问每个字节,记住低字节序的值,然后将计算出的值手动分配给结构的字段吗?

Do I really need to access each byte, compose a value with lower Endian in mind, and manually assign the calculated value to the structures' fields?

修改

我使用GCHandleIntPtr找到了这个建议:

I found this suggestion using GCHandle and IntPtr: Is there a way to convert a structure to a byte array?

(肯定需要包装.)

这是我所希望的最好的吗?

Is this the best I can hope for?

推荐答案

一般将字节数组复制到结构记录中:

To copy a bytes array into a structure record in general:

'Marshal, GCHandle, GCHandleType:
Imports System.Runtime.InteropServices

'Copies a bytes array into a structure record.
Public Shared Sub BytesToStructure(Of T As Structure)(abBytes As Byte(),
    ByRef oStruct As T)

    Dim hBytes As GCHandle
    Dim iBytes As IntPtr

    'Obtain a handle to the byte array, pinning it so that the garbage
    'collector does not move the object. This allows the address of the 
    'pinned structure to be taken. Requires the use of Free when done.
    hBytes = GCHandle.Alloc(abBytes, GCHandleType.Pinned)
    Try
        'Obtain the byte array's address.
        iBytes = hBytes.AddrOfPinnedObject()

        'Copy the byte array into the record.
        oStruct = Marshal.PtrToStructure(Of T)(iBytes)
    Finally
        hBytes.Free()
    End Try
End Sub

一种实际的应用(以及问题的答案)是读取结构记录,这些记录被写回到文件中,再回到这些结构记录中.

One practical application (and the answer to the question) is to read structure records, which were written into a file back into such structure records.

'Expects to find a structure of type T at the actual position of the 
'specified open filestream oFS. Reads this structure and copies
'it to the structure variable specified in oStruct.
Public Shared Sub ReadBytesToStructure(Of T As Structure) _
    (oFS As FileStream, ByRef oStruct As T)

    Dim iStructLen As Integer
    Dim abStreamData As Byte()

    'From the file's current position, read the number of bytes required to
    'fill the structure, into the byte array abStreamData.
    iStructLen = Marshal.SizeOf(oStruct)
    ReDim abStreamData(0 To iStructLen - 1)
    oFS.Read(abStreamData, 0, iStructLen)

    'Copy the read bytes into the provided record.
    BytesToStructure(Of T)(abStreamData, oStruct)
End Sub

这篇关于将文件中间的结构提取到我的结构中,而不是逐字节访问文件字节并编写其值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆