Каков наилучший способ чтения / записи содержимого массива из / в двоичные файлы в C #? - PullRequest
2 голосов
/ 08 апреля 2010

Я хотел бы прочитать и записать содержимое больших необработанных файлов томов (например, МРТ-сканирования). Эти файлы представляют собой последовательность, например, 32 x 32 x 32 с плавающей точкой, поэтому они хорошо отображаются на одномерные массивы. Я хотел бы иметь возможность читать содержимое файлов двоичных томов в одномерные массивы, например, float или ushort (в зависимости от типа данных двоичных файлов) и аналогичным образом экспортируйте массивы обратно в файлы необработанных томов.

Какой лучший способ сделать это с C #? Читать / записывать их по 1 элементу за раз с помощью BinaryReader / BinaryWriter? Читайте их по кусочкам в байтовые массивы с помощью FileStream.Read, а затем делайте System.Buffer.BlockCopy между массивами? Написать свой собственный Reader / Writer?

РЕДАКТИРОВАТЬ: кажется, что невозможно работать с> 2 ГБ массивов, но вопрос по-прежнему стоит за меньшие массивы (около 256 МБ или около того)

1 Ответ

3 голосов
/ 08 апреля 2010

Вы не собираетесь получать массивы с данными более 2 ГБ. Из того, что я помню, есть ограничение CLR 1 ГБ на объект. Это возможно , которое было отменено для .NET 4 на 64-битной платформе, но я не слышал об этом.

РЕДАКТИРОВАТЬ: Согласно этой статье ограничение составляет 2 ГБ, а не 1 ГБ - но вы все равно не сможете управлять более 2 ГБ.

Вам действительно нужно хранить все данные в памяти одновременно? Можете ли вы работать с кусками этого одновременно?

РЕДАКТИРОВАТЬ: Хорошо, теперь речь идет только о чтении из файла в массив с плавающей точкой? Вероятно, проще всего прочитать куски (используя BinaryReader.Read(byte[], int, int) или BinaryReader.ReadBytes(int)), а затем использовать Buffer.BlockCopy для эффективного преобразования байтов в число с плавающей запятой и т. Д. Обратите внимание, что это будет чувствительно к порядку байтов. Если вы хотите выполнить более надежное преобразование (чтобы позже можно было изменить порядок байтов или запустить на платформе с прямым порядком байтов), вам, вероятно, потребуется повторно вызывать ReadFloat().

Насколько вы убеждены, что у вас действительно есть проблема с производительностью в этой области кода? Стоит сделать простейшую вещь, которая будет работать, а затем профилировать ее, чтобы начать с ...

...