问题描述
我试图读取使用C#的二进制数据。我对在我想读的文件的数据的布局的所有信息。我能读由大块大块的数据,即获得第一个40字节的数据将其转换为字符串,得到下一个40个字节的...
I'm trying to read binary data using C#. I have all information about the layout of the data in the files I want to read. I'm able to read the data "chunk by chunk", i.e. getting the first 40 bytes of data converting it to a string, get the next 40 bytes, ...
由于至少有三个不同的slighlty版本的数据,我想将数据直接读入一个结构。它只是感觉比通过阅读它逐行这么多的权利。
Since there are at least three slighlty different version of the data, I would like to read the data directly into a struct. It just feels so much more right than by reading it "line by line".
我曾尝试以下方法,但无济于事:
I have tried the following approach but to no avail:
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();
\r
流是打开的FileStream从中我已经开始从阅读。我使用Marshal.PtrToStructure时得到一个AccessViolationException。
The stream is an opened FileStream from which I have began to read from. I get an AccessViolationException when using Marshal.PtrToStructure.
流包含比我试图阅读,因为我在文件的结尾数据不感兴趣的更多信息。
The stream contains more information than I'm trying to read since I'm not interested in data at the end of the file.
该结构的定义是这样的:
The struct is defined like:
[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;
}
\r
例子code由原来的改变,使这个问题更短。
The examples code is changed from original to make this question shorter.
我将如何从一个文件到一个结构读取二进制数据?
How would I read binary data from a file into a struct?
推荐答案
问题是在字符串取值在你的结构。我发现,封送类型,如字节/短路/ int是没有问题的;但是当你需要集结成一个复杂的类型,如字符串,你需要你的结构来显式地模仿非托管类型。你可以用的MarshalAs ATTRIB做到这一点。
The problem is the strings in your struct. I found that marshaling types like byte/short/int is not a problem; but when you need to marshal into a complex type such as a string, you need your struct to explicitly mimic an unmanaged type. You can do this with the MarshalAs attrib.
有关你的榜样,下面应该工作:
For your example, the following should work:
[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;
}
这篇关于读取二进制文件到一个结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!