有没有一种方法可以像在C语言中那样,将二进制数据从文件读入数组中,并且可以传递任何类型的指针到I/O函数中?我想到了类似于BinaryReader::ReadBytes()这样的东西,但是它返回的是byte[]类型,我无法将其转换为所需的数组指针类型。
结构体
,[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
struct MyFixedStruct
{
//..
}
您可以使用以下方法一次性读取它:
public static T ReadStruct<T>(Stream stream)
{
byte[] buffer = new byte[Marshal.SizeOf(typeof(T))];
stream.Read(buffer, 0, Marshal.SizeOf(typeof(T)));
GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
T typedStruct = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
handle.Free();
return typedStruct;
}
这段代码读取一个字节数组,其大小覆盖了struct
的大小,然后将字节数组转换为结构体。可以按照以下方式使用:
MyFixedStruct fixedStruct = ReadStruct<MyFixedStruct>(stream);
struct
可以包含数组类型,只要指定了数组长度,如下:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct MyFixedStruct
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public int[] someInts; // 5 int's
//..
};
编辑:
我看到您只想读取一个short
数组 - 在这种情况下,只需读取字节数组并使用Buffer.BlockCopy()
进行转换即可获得所需的数组:
byte[] someBytes = ..
short[] someShorts = new short[someBytes.Length/2];
Buffer.BlockCopy(someBytes, 0, someShorts, 0, someBytes.Length);
这种方法非常高效,相当于底层使用C++中的memcpy
。当然,你所拥有的唯一额外开销是原始字节数组将被分配和稍后进行垃圾回收。这种方法也适用于任何其他原始数组类型。
将序列化的结构数组存储在文件中如何?您可以轻松地构建结构体数组。不确定如何像在C中那样流式传输文件。
使用流类如何?它为字节序列提供了通用视图。