К сожалению, действительно простого решения не существует. Вы можете попробовать что-то вроде этого:
Stream s1, s2;
byte[] buffer = new byte[4096];
int bytesRead = 0;
while (bytesRead = s1.Read(buffer, 0, buffer.Length) > 0) s2.Write(buffer, 0, bytesRead);
s1.Close(); s2.Close();
Но проблема в том, что другая реализация класса Stream может вести себя по-разному, если нечего читать. Поток, считывающий файл с локального жесткого диска, вероятно, будет блокироваться до тех пор, пока операция чтения не прочитает достаточно данных с диска, чтобы заполнить буфер, и вернет меньше данных только в том случае, если достигнет конца файла. С другой стороны, чтение потока из сети может вернуть меньше данных, даже если осталось больше данных для получения.
Всегда проверяйте документацию определенного класса потока, который вы используете, прежде чем использовать универсальное решение.