Вопрос по memorystream, stream, wrapper, stream-wrapper, c# – Композитный Stream Wrapper, обеспечивающий частичную MemoryStream и полный оригинальный Stream

5

Кто-нибудь знает решение с составным потоком, которое предварительно загрузит первую часть потока в MemoryStream и сохранит оставшуюся часть как исходный поток, к которому будет обращаться, когда последующие части потребуются по мере необходимости?

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

Я надеюсь, что это решение, которое кто-то мог решить раньше, возможно, для оптимизации производительности чтения большого FileStream.

В моем случае яЯ пытаюсь обойти ошибку Windows Phone 8 при чтении больших файлов с SD-карты. Подробнее о проблеме ям, пытаюсь обойти кругом, предусмотрен в этом ответе:https://stackoverflow.com/a/17355068/250254

Я неНе думаю, что это правильный способ решения проблемы ... сколько данных вы намереваетесь загрузить в MemoryStream? Если я правильно понял проблему, проблема Seek возникает для любого смещения в младших 32 битах long, что означает, что вам нужно будет загрузить 4 ГБ данных в память ... Thomas Levesque
Взгляни наstackoverflow.com/questions/3879152/... Russ Cam
@RussCam - спасибо за это, высоко ценится! Не совсем та же проблема, что и мои потоки перекрываются, но яя попробую и посмотрю, есть лиЧто-то, что я могу приспособить. Gavin
@ThomasLevesque - экспериментируя кажется, что около 400408 позиции проблема может уйти. Таким образом, около 0,4 МБ должно быть сохранено в потоке памяти. Все еще экспериментирую, чтобы я мог ошибаться! Gavin

Ваш Ответ

1   ответ
5

выЯ сначала упаду на OutOfMemoryException. Позволять'немного сосредоточиться на ошибке, яЯ немного упросту код, чтобы сделать его читаемым:

DistanceToMove = (offset & 0xffffffff00000000L) >> 32;
DistanceToMoveHigh = offset & 0xffffffffL;
SetFilePointer(this.m_handle, lDistanceToMove, ref lDistanceToMoveHigh, begin);

Программист Microsoft случайно поменял местами низкие и высокие значения. Ну, так что вы можете исправить ошибку. Поменяйте их местами, чтобы ошибка поменяла их так, как вы этого хотите:

public static void SeekBugWorkaround(Stream stream, long offset, SeekOrigin origin) {
    ulong uoffset = (ulong)offset;
    ulong fix = ((uoffset & 0xffffffffL) << 32) | ((uoffset & 0xffffffff00000000L) >> 32);
    stream.Seek((long)fix, origin);
}

В случае, если это нужно сказать, очевидно, вам нужно рассчитывать на то, что Microsoft в конечном итоге исправит эту ошибку. Сложно предсказать, когда начнутся азартные игры на следующей версии релиза Есть некоторые шансы, что вы можете автоматически определить это, хотя это не так.Совершенно очевидно, что собирается делать Microsoft, так как эта ошибка настолько серьезна. Возвращаемое значение Seek (), а также возвращаемое значение свойства Position страдают от той же ошибки. Так что постарайтесь в позиции 1 и убедитесь, что вы получаете 1 обратно.

Для всех, кому нужна потоковая оболочка, которую можно включить в свое решение -github.com/gavinharriss/ExternalStorageFileWrapper-wp8 Gavin
@CoryNelson - Должен быть в состоянии проверить версию ОС Windows Phone, я надеюсь, что обойти это исправление в будущем выпуске. Gavin
@ Hans-Passant - Спасибо за это - высоко ценится. Я'Я буду играть на следующий день или два, чтобы посмотреть, смогу ли я заставить его работать (этоs для неоплачиваемой стороны проекта, который я делаю). Я предполагаю, что я'Я реализую класс потока-оболочки, который переопределяет метод Seek, используя вашу логику. Gavin
@ThomasLevesque That 'Это действительно хороший вопрос. MuiBienCarlota

Похожие вопросы