Читайте из огромного MemoryStream в C # - PullRequest
6 голосов
/ 06 сентября 2010

Я использую BinaryReader (MemoryStream(MyByteArray)), чтобы читать записи переменного размера и обрабатывать их все в памяти.Это хорошо работает до тех пор, пока размер моего байта, который находится в массиве, составляет менее 1,7 ГБ.После этого (который является максимальным размером целого числа в моей 64-битной системе) вы не можете создать больший байтовый массив, хотя у меня достаточно реальной памяти.Поэтому мое решение состояло в том, чтобы прочитать байтовый поток и разбить его на несколько байтовых массивов.

Теперь, однако, я не могу «читать» через границы байтового массива, и, поскольку мои данные находятся в переменном формате, я не могуубедитесь, что байтовые массивы всегда завершаются для всей записи.

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

Как мне решить эту проблему?

Ответы [ 2 ]

4 голосов
/ 06 сентября 2010

Редактировать : Читая основы, я понимаю, что отображаемые в память файлы могут быть медленнее, чем обычный ввод / вывод для последовательного доступа.

Вы пробовали что-то подобное:

var stream = new FileStream("data", 
    FileMode.Open, 
    FileAccess.Read, 
    FileShare.Read, 
    16 * 1024, 
    FileOptions.SequentialScan)

var reader = new BinaryReader(stream);

Если ваши данные находятся в файле, и вы можете использовать .NET 4.0, рассмотрите возможность использования MemoryMappedFile.

Затем можно использовать MemoryMappedViewStream для получения потока или используйте MemoryMappedViewAccessor для получения BinaryReader -подобного интерфейса.

2 голосов
/ 06 сентября 2010

Для слишком больших потоков вы не должны пытаться сбросить его в MemoryStream - используйте вместо этого такие вещи, как FileStream, и говорите непосредственно с диском. Встроенной буферизации, как правило, достаточно, или вы можете настроить ее с помощью таких вещей, как BufferedStream (но мне это редко требуется - но тогда я, как правило, включаю свой собственный буфер для обработки данных).

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

...