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

时间:2011-08-16 12:14:53

标签: c#

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

3 个答案:

答案 0 :(得分:5)

如果您有固定尺寸struct

[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。您当然唯一的其他开销是分配原始字节数组,然后进行垃圾回收。这种方法也适用于任何其他原始数组类型。

答案 1 :(得分:0)

如何在文件中存储结构的序列化数组?您可以轻松地构建结构数组。不知道如何流式传输文件,就像在C中一样。

答案 2 :(得分:-1)

如何使用Stream Class,因为它提供了字节序列的通用视图。