我试图阅读的二进制数据使用。我有所有的相关信息的布局中的数据文件,我想读。我可以读取的数据"区块的区块",即得到的第一个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();

流是一个开放的文件流从我开始阅读。我得到一个 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;
}

例代码被改变,从原来使这个问题更短。

我怎么会读过的二进制数据文件变成一个结构?

没有正确的解决方案

其他提示

问题是 字符串在你结构。我发现这封送类似的字节/短/int不是一个问题;但是当你需要汇集成一个复杂的类型,例如串,你需要你的结构明确地模仿的一个非管理型。你可以这样做的MarshalAs attrib.

对你的例子,下面该工作:

[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;
}

这里是我的使用。
这个工作成功地为我读的便携式可执行格式。
这是一个通用功能,所以 T 是你的 struct 类型。

public static T ByteToType<T>(BinaryReader reader)
{
    byte[] bytes = reader.ReadBytes(Marshal.SizeOf(typeof(T)));

    GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
    T theStructure = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
    handle.Free();

    return theStructure;
}

作为罗尼说的,我会使用BinaryReader和阅读的每一个领域。我找不到链接到该条与这个信息,但它已经观察到,使用BinaryReader阅读的每一个领域可以更快的速度比元帅。PtrToStruct,如果该结构含有低于30-40或使的领域。我会发布的文章链接,当我找到它。

该文章的链路是: http://www.codeproject.com/Articles/10750/Fast-Binary-File-Reading-with-C

当封送一系列的结构,PtrToStruct收益上手更快,因为可以认为该领域最为领域*阵列的长度。

我有没有运气用BinaryFormatter,我猜测我已经有一个完整的结构相匹配的文件的内容完全一致。我意识到,在结束我是不是感兴趣的在很多的文件内容无论如何,所以我去解读的一部分流入bytebuffer,然后将其转换使用

Encoding.ASCII.GetString()

对于字符串

BitConverter.ToInt32()

为整数。

我将需要能够分析更多的文件以后,但这个版本的我只是几分行代码。

我没有看到任何问题与你的代码。

只要我的头,如果你试图做手动?它的工作原理?

BinaryReader reader = new BinaryReader(stream);
StructType o = new StructType();
o.FileDate = Encoding.ASCII.GetString(reader.ReadBytes(8));
o.FileTime = Encoding.ASCII.GetString(reader.ReadBytes(8));
...
...
...

也试试

StructType o = new StructType();
byte[] buffer = new byte[Marshal.SizeOf(typeof(StructType))];
GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
Marshal.StructureToPtr(o, handle.AddrOfPinnedObject(), false);
handle.Free();

然后使用 缓冲[] 在你BinaryReader而不是读取数据文件流来看看你是否仍获得访问冲突的例外。

我有没有运气的使用 BinaryFormatter,我想我有 有一个完整的结构相匹配 该文件的内容完全一致。

这是有道理的,BinaryFormatter具有其自己的数据格式,完全不符合你的。

试试这个:

using (FileStream stream = new FileStream(fileName, FileMode.Open))
{
    BinaryFormatter formatter = new BinaryFormatter();
    StructType aStruct = (StructType)formatter.Deserialize(filestream);
}

阅读直到结构是邪恶的许多一C节目已经下降,因为不同的字节的顺序,不同的编译器实现的领域、包装、词。...

你是最好的serialising和deserialising字节.使用建立中东西如果你想要的,或只是得到用于BinaryReader.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top