将文件中间的结构提取到我的结构中,而不是逐字节访问文件字节并编写其值 [英] Extracting structs in the middle of a file into my structures other than accessing the file byte for byte and compose their value
问题描述
二进制文件具有以下布局:
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?
修改
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屋!