MemoryMappedViewAccessor.ReadArray如何执行方法内部工作

发布于 2024-11-18 13:16:09 字数 1007 浏览 4 评论 0原文

我一直在 BinaryReader 或 Stream 中有一种快速读取数组的方法。自从 MS 引入了 MemoryMappedFiles 以来,就出现了一个 MemoryMappedViewAccessor 类,它有一个名为 ReadArray 的方法来读取数组。

有人知道这个方法是如何工作的吗?目前从二进制流读取数组是很糟糕的。您首先必须以字节形式读取流,然后将字节流复制到目标数组格式。如果能一步到位就好了。

我尝试在 VS2010 中启用 .NET-Framework 源代码步进,但它不起作用。

目前,我读取了几种原始数组数据类型的数据,如下所示:

public static float[] ReadSingles(this Stream stream_in, int count)
    {
        FileStream fileStream = stream_in as FileStream;

        float[] Data = new float[count];

        if (count == 0) return Data;

            fixed (float* dataptr = &Data[0])
            {
                if ((fileStream == null) || (StreamExt.Mode == StreamExtMode.Conventional))
                {
                    byte[] bts = ReadBytes(stream_in, count * sizeof(float));// stream_in.ReadBytes(count * sizeof(float));
                    Marshal.Copy(bts, 0, new IntPtr(dataptr), bts.Length);
            }
        }

        return Data;
    }

对此有一个好的答案吗?

谢谢 马丁

I have always been in the BinaryReader or Stream to have a method to read array in quick way. Since MS has introduced the MemoryMappedFiles there has been one class MemoryMappedViewAccessor that has a method which is called ReadArray to read arrays.

Has someone an idea how this method works. Currently it's horrible to read arrays from a binary stream. You first have to read the stream as bytes and them copy the byte stream into the target array format. It would be nice to have it in one step.

I tried to enable to .NET-Framework source-stepping in VS2010 but it doesn't work.

Currently I read my data for several primitive array datatypes, like this:

public static float[] ReadSingles(this Stream stream_in, int count)
    {
        FileStream fileStream = stream_in as FileStream;

        float[] Data = new float[count];

        if (count == 0) return Data;

            fixed (float* dataptr = &Data[0])
            {
                if ((fileStream == null) || (StreamExt.Mode == StreamExtMode.Conventional))
                {
                    byte[] bts = ReadBytes(stream_in, count * sizeof(float));// stream_in.ReadBytes(count * sizeof(float));
                    Marshal.Copy(bts, 0, new IntPtr(dataptr), bts.Length);
            }
        }

        return Data;
    }

Is there a good answer to this.

Thanks
Martin

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

稀香 2024-11-25 13:16:09

它归结为一个 extern 方法,所以简而言之:我们无法直接看到。它不是在托管代码中完成的,而是由 CLI 主机完成的:

[MethodImpl(MethodImplOptions.InternalCall)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
private static extern unsafe void PtrToStructureNative(
         byte* ptr, TypedReference structure, uint sizeofT);

重新您现有的代码; IMO,这里的问题是您选择分配 count * sizeof(float) 如果您的目的是避免额外的 byte[] 开销,我会创建一个 较小的缓冲区(例如,Max(count, 1000) * sizeof(float))并使用循环,逐步填充数据。

另外,如果您不需要一次需要所有浮点数,请考虑使用迭代器块,这将削减此处的内存开销(但这意味着您只能以序列的形式访问项目,而不能随机访问)。

It boils down to an extern method, so in short: we can't see directly. It isn't done in managed code, but by the CLI host:

[MethodImpl(MethodImplOptions.InternalCall)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
private static extern unsafe void PtrToStructureNative(
         byte* ptr, TypedReference structure, uint sizeofT);

Re your existing code; IMO, the issue here is your choice to allocate count * sizeof(float) If your intention is to avoid the additional byte[] overhead, I would create a smaller buffer (say, Max(count, 1000) * sizeof(float)) and use a loop, filling in Data progressively.

Also, if you don't need all the floats at once, consider an iterator block instead, which will slash the memory overheads here (but will mean you only have access to the items as a sequence, not random access).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文