Rob*_*und 52 c# io struct binaryfiles
我正在尝试使用C#读取二进制数据.我有关于我想要阅读的文件中数据布局的所有信息.我能够读取数据"chunk by chunk",即获取前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();
Run Code Online (Sandbox Code Playgroud)
该流是一个打开的FileStream,我已经开始从中读取.我AccessViolationExceptio在使用时得到了一个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;
}
Run Code Online (Sandbox Code Playgroud)
示例代码从原始代码更改为使此问题更短.
如何将二进制数据从文件读入结构?
Ish*_*eel 29
问题是结构中的字符串 s.我发现像byte/short/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;
}
Run Code Online (Sandbox Code Playgroud)
小智 11
这是我正在使用的.
这成功地为我阅读可移植可执行格式.
这是一个通用功能,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;
}
Run Code Online (Sandbox Code Playgroud)
正如罗尼所说,我会使用BinaryReader并分别读取每个字段.我找不到带有此信息的文章的链接,但据观察,如果struct包含少于30-40个字段,使用BinaryReader读取每个单独的字段可能比Marshal.PtrToStruct更快.当我找到它时,我会发布文章的链接.
该文章的链接位于:http://www.codeproject.com/Articles/10750/Fast-Binary-File-Reading-with-C
当编组结构数组时,PtrToStruct可以更快地获得上风,因为您可以将字段计数视为字段*数组长度.
尝试这个:
using (FileStream stream = new FileStream(fileName, FileMode.Open))
{
BinaryFormatter formatter = new BinaryFormatter();
StructType aStruct = (StructType)formatter.Deserialize(filestream);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
63064 次 |
| 最近记录: |