меры предосторожности для чтения из потока памяти в c # - PullRequest
3 голосов
/ 18 сентября 2009

Эй, ребята, я недавно наткнулся на эту веб-страницу http://www.yoda.arachsys.com/csharp/readbinary.html, объясняющую, какие меры предосторожности следует соблюдать при чтении из файлового потока. Суть в том, что следующий код не всегда работает:

// Bad code! Do not use!
FileStream fs = File.OpenRead(filename);
byte[] data = new byte[fs.Length];
fs.Read (data, 0, data.Length);

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

У меня вопрос: должны ли вы соблюдать те же меры предосторожности при чтении из потока памяти и при каких обстоятельствах чтение может вернуться до того, как будут прочитаны все байты?

Спасибо, Бас

Ответы [ 4 ]

5 голосов
/ 18 сентября 2009

Что ж, я полагаю, что текущая реализация MemoryStream всегда будет заполнять буфер, если это возможно - если только у вас нет какого-то злого класса, полученного из него. Хотя это не гарантировано, насколько я вижу. Документация даже содержит предупреждение:

Реализация может возвращать меньше байтов, чем запрошено, даже если конец потока не достигнут.

Лично я всегда защищал бы это, если только это не облегчит намного . Вы никогда не знаете, когда кто-то изменит тип потока, и не заметите, что произошло.

Обычно с MemoryStream я хочу, чтобы все байты были одновременно: поэтому я вызываю MemoryStream.ToArray. Это гарантированно сработает, и если кто-то изменит код, чтобы не использовать MemoryStream, он не сможет скомпилироваться, так как этот член только на MemoryStream. Для общих потоков я использую служебный метод, который полностью читает из потока и возвращает байтовый массив.

1 голос
/ 18 сентября 2009

Не могу придумать ни одной причины для нормального MemoryStream. Неуправляемый может быть другой историей.

В любом случае, команда GetBuffer() ToArray() всегда удобна. :)

0 голосов
/ 18 сентября 2009

Вот что MSDN говорит об этом:

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

и

Реализация может быть возвращена бесплатно. меньше байтов, чем запрошено, даже если Конец потока не был достиг.

Обратите внимание на термин «реализация ...».

0 голосов
/ 18 сентября 2009

Да, вы всегда должны знать, сколько байтов было фактически прочитано из потока при вызове Read. Причина роута может варьироваться в зависимости от типа потока, но, по сути, возвращаемое значение будет меньше фактического размера буфера всякий раз, когда вы пытаетесь прочитать за пределами конца потока.

...