从文件中读取非字节数组而不必使用循环?

kar*_*erx 3 c#

有没有办法从文件中读取二进制数据到像C中的数组,我可以将任何类型的指针传递给i/o函数?我想像BinaryReader :: ReadBytes(),但返回一个byte [],我无法转换为所需的数组指针类型.

Bro*_*ass 5

如果您有固定的尺寸 struct

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
struct MyFixedStruct
{
  //..
}
Run Code Online (Sandbox Code Playgroud)

然后您可以使用以下方式一次性读取它:

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;
}
Run Code Online (Sandbox Code Playgroud)

这将读取覆盖其大小struct的字节数组,然后将字节数组封送到结构中.你可以像这样使用它:

MyFixedStruct fixedStruct =  ReadStruct<MyFixedStruct>(stream);
Run Code Online (Sandbox Code Playgroud)

struct可以包括数组类型,只要指定了阵列的长度,即:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct MyFixedStruct
{
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
    public int[] someInts; // 5 int's
    //..
};
Run Code Online (Sandbox Code Playgroud)

编辑:

我看到你只想读取short数组 - 在这种情况下只需读入字节数组并用于Buffer.BlockCopy()转换为你想要的数组:

byte[] someBytes = ..
short[] someShorts = new short[someBytes.Length/2];
Buffer.BlockCopy(someBytes, 0, someShorts, 0, someBytes.Length);
Run Code Online (Sandbox Code Playgroud)

这非常有效,相当于memcpyC++中的一个.您当然唯一的其他开销是分配原始字节数组,然后进行垃圾回收.这种方法也适用于任何其他原始数组类型.