2009-04-05 5 views
1

Я просто пишу простой метод, который считывает данные из общего потока, что означает, что это может быть файл FileStream или NetworkStream, не зная его длины. Я снова читаю поток в байт [] и выталкиваю данные в другой поток или что угодно. Мой вопрос: как я могу заметить, что поток закончен? Я попытался вернуться, когда Чтение метод возвращает 0 - это правильный способ сделать это? Кажется, что это нормально для чтения файлов, но иногда встречаются проблемы для чтения данных из сети.Как я могу сказать, что поток был прочитан до конца?

ответ

5

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

Сетевые потоки в порядке с этим - они будут блокироваться до тех пор, пока не будут получены какие-либо данные или поток не будет отключен. Посмотрите документацию для Stream.Read:

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

+0

Я стою исправленный, спасибо. – JoshBerke

+0

Тогда кажется, что нам нужно знать длину данных для сетевого потока? –

+0

Знание длины помогает, но это не обязательно. –

0

Для сетевых потоков, если Stream.ReadByte() возвращает что-либо меньшее, чем 0, вы знаете, что поток был прочитан до конца.

+0

Вы хотите сказать, что я должен поместить вызов метода ReadByte() сразу после метода Read в теле цикла для NetworkStream? –

0

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

Например, если поток отключен (в отличие от другой стороны, просто закрывающей сокет), вы можете получить исключение IOException. Всегда завершайте вызовы ввода-вывода в обработчиках исключений, если вы абсолютно не уверены, что они не могут генерировать исключение.

+0

Просто потому, что они могут генерировать исключения, это не значит, что вы должны обернуть их обработчиками. По моему опыту, если вызов IO вызывает IOException, метод * make * этот вызов обычно должен просто разрешать исключение. У меня, как правило, очень мало блоков try/catch - обычно чуть выше вершины. –

+0

Я не имел в виду, что ты должен поймать это сразу. Но его нужно поймать в какой-то момент. –

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