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

5

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

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

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

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

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

Ваш Ответ

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 обратно.

Интересно, как такая ошибка могла попасть в производство незамеченной ... У них нет модульных тестов в MS? Thomas Levesque
@CoryNelson - Должен быть в состоянии проверить версию ОС Windows Phone, я надеюсь, что обойти это исправление в будущем выпуске. Gavin
Да, это звучит как кошмар с совместимостью с прямой совместимостью! Cory Nelson
Для всех, кому нужна потоковая оболочка, которую можно включить в свое решение -github.com/gavinharriss/ExternalStorageFileWrapper-wp8 Gavin
@ Hans-Passant - Спасибо за это - высоко ценится. На следующий день или два у меня будет спектакль, чтобы увидеть, смогу ли я заставить его работать (это для неоплачиваемого побочного проекта, который я делаю). Я предполагаю, что я реализую класс потока-оболочки, который переопределяет метод Seek, используя вашу логику. Gavin

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