Как внутренне работает метод MemoryMappedViewAccessor.ReadArray <T> - PullRequest
1 голос
/ 06 июля 2011

Я всегда был в BinaryReader или Stream, чтобы иметь метод для быстрого чтения массива.Так как MS представила MemoryMappedFiles, был один класс MemoryMappedViewAccessor, у которого есть метод, который называется ReadArray для чтения массивов.

Кто-то знает, как работает этот метод.В настоящее время ужасно читать массивы из двоичного потока.Сначала вы должны прочитать поток как байты, а затем скопировать поток байтов в формат целевого массива.Было бы неплохо сделать это за один шаг.

Я попытался включить .NET-Framework с пошаговым переводом исходного кода в VS2010, но он не работает.

В настоящее время я читаю свои данные для нескольких типов примитивных массивов, например:

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;
    }

Есть ли хороший ответ на этот вопрос?

Спасибо, Мартин

1 Ответ

2 голосов
/ 06 июля 2011

Это сводится к методу extern, так что вкратце: мы не можем видеть напрямую .Это не делается в управляемом коде, но хостом CLI:

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

Re существующего кода;ИМО, проблема здесь в том, что вы решили выделить count * sizeof(float) Если вы намерены избежать дополнительных издержек byte[], я бы создал буфер на меньший (скажем, Max(count, 1000) * sizeof(float)) и использовал бы цикл,заполнение Data постепенно.

Кроме того, если вам не нужны все типы с плавающей запятой, рассмотрите вместо этого блок итератора, который косой чертой потребляет дополнительные ресурсы памяти (но это будет означатьу вас есть доступ только к элементам как к последовательности, а не к произвольному доступу).

...