2010-09-06 2 views
6

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

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

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

Как справиться с этой проблемой?

+0

Вы должны предотвратить загрузку массива байтов этого размера в память. Разве невозможно реализовать потоковое решение, в котором вы загружаете только части массива в память (буфер)? Вам нужен произвольный доступ к этим байтам? Или вы можете использовать прямое решение, где вы можете читать поток от начала до конца, обрабатывая его (и не оглядываясь). Откуда этот массив байтов? Файл, веб-сервис, ...? –

ответ

4

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

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

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

var reader = new BinaryReader(stream); 

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

Чтобы получить поток или используйте MemoryMappedViewAccessor, вы можете использовать MemoryMappedViewStream, чтобы получить интерфейс BinaryReader.

+1

Да. Я пробовал это - к сожалению, MemoryMappedFiles действительно очень медленный. – ManInMoon

2

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

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

+0

Да. Он сжимается - эффективно, и я отказываюсь от него с помощью своей собственной логики. Но чтение с диска происходит слишком медленно. Все - я использую параллельную обработку этого огромного файла данных, и его наличие на диске будет иметь всевозможные разногласия. – ManInMoon

+0

Использование memoryStrea, все в памяти - отлично работает для меня - за исключением того, что теперь мои данные переросли этот суровый максимальный размер bytearray. – ManInMoon

+0

Надеюсь, вы закончили сначала читать 300 писем, иначе десерт (SO) для вас! –

Смежные вопросы