Невозможно прочитать после конца потока

#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;»