#c# #stream
#c# #поток
Вопрос:
Я использовал какой-то быстрый метод для записи файла из потока, но это еще не сделано. Я получаю это исключение и не могу найти причину:
Unable to read beyond the end of the stream
Есть ли кто-нибудь, кто мог бы помочь мне отладить это?
public static bool WriteFileFromStream(Stream stream, string toFile)
{
FileStream fileToSave = new FileStream(toFile, FileMode.Create);
BinaryWriter binaryWriter = new BinaryWriter(fileToSave);
using (BinaryReader binaryReader = new BinaryReader(stream))
{
int pos = 0;
int length = (int)stream.Length;
while (pos < length)
{
int readInteger = binaryReader.ReadInt32();
binaryWriter.Write(readInteger);
pos = sizeof(int);
}
}
return true;
}
Большое спасибо!
Ответ №1:
На самом деле это не ответ на ваш вопрос, но этот метод мог бы быть намного проще, например:
public static void WriteFileFromStream(Stream stream, string toFile)
{
// dont forget the using for releasing the file handle after the copy
using (FileStream fileToSave = new FileStream(toFile, FileMode.Create))
{
stream.CopyTo(fileToSave);
}
}
Обратите внимание, что я также удалил возвращаемое значение, поскольку оно практически бесполезно, поскольку в вашем коде есть только 1 оператор возврата
Кроме того, вы выполняете проверку длины потока, но многие потоки не поддерживают проверку длины.
Что касается вашей проблемы, вы сначала проверяете, находится ли поток в конце. Если нет, вы прочитали 4 байта. Вот в чем проблема. Допустим, у вас входной поток в 6 байт. Сначала вы проверяете, находится ли поток в конце. Ответ отрицательный, поскольку осталось 6 байт. Вы читаете 4 байта и проверяете снова. Конечно, ответ по-прежнему отрицательный, поскольку осталось 2 байта. Теперь вы читаете еще 4 байта, но это, конечно, не удается, поскольку есть только 2 байта. (ReadInt32 считывает следующие 4 байта).
Комментарии:
1. Удивительно, так намного проще, как вы сказали! БОЛЬШОЕ спасибо 🙂
Ответ №2:
Я предполагаю, что во входном потоке есть только целые числа (Int32). Вам нужно протестировать PeekChar()
метод,
while (binaryReader.PeekChar() != -1)
{
int readInteger = binaryReader.ReadInt32();
binaryWriter.Write(readInteger);
}
Комментарии:
1. обратите внимание, что это вообще неэффективно.
PeekChar
фактически сохранит текущую позицию из основного потока, прочитает значение int и снова установит позицию!
Ответ №3:
Вы выполняете while (pos < длина), а длина — это фактическая длина потока в байтах. Таким образом, вы эффективно подсчитываете байты в потоке, а затем пытаетесь прочитать такое количество целых чисел (что неверно). Вы могли бы принять длину за поток.Длина / 4, поскольку Int32 равен 4 байтам.
Ответ №4:
попробуйте
int length = (int)binaryReader.BaseStream.Length;
Ответ №5:
После чтения потока с помощью двоичного считывателя позиция потока находится в конце, вы должны установить позицию равной нулю «stream.position=0;»