8

The testing.res file is 240MB size. I want to read it. But im getting the error on this line:

int v = br.ReadInt32();

EndOfStreamException Unable to read beyond the end of the stream

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            R();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        public void R()
        {
            using (var br = new System.IO.BinaryReader(File.Open(@"d:\testing.res", FileMode.Open)))
            {
                // 2.
                // Position and length variables.
                int pos = 0;
                // 2A.
                // Use BaseStream.
                int length = (int)br.BaseStream.Length;
                while (br.BaseStream.Position < length)
                {
                    // 3.
                    // Read integer.
                    int v = br.ReadInt32();
                    textBox1.Text = v.ToString();
                }

            }
        }
    }
}

The exception:

System.IO.EndOfStreamException was unhandled
  Message=Unable to read beyond the end of the stream.
  Source=mscorlib
  StackTrace:
       at System.IO.BinaryReader.FillBuffer(Int32 numBytes)
       at System.IO.BinaryReader.ReadInt32()
       at WindowsFormsApplication1.Form1.R() in D:\C-Sharp\BinaryReader\WindowsFormsApplication1\WindowsFormsApplication1\Form1.cs:line 41
       at WindowsFormsApplication1.Form1..ctor() in D:\C-Sharp\BinaryReader\WindowsFormsApplication1\WindowsFormsApplication1\Form1.cs:line 19
       at WindowsFormsApplication1.Program.Main() in D:\C-Sharp\BinaryReader\WindowsFormsApplication1\WindowsFormsApplication1\Program.cs:line 18
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: 
Daniel Lip
  • 3,867
  • 7
  • 58
  • 120
  • This answer had helped me when I was getting the same error: https://stackoverflow.com/questions/23865865/reading-xls-stream-with-getresponsestream-and-spreadsheetdocument-open – gabics Sep 17 '17 at 02:21

3 Answers3

4

You should use a more reliable way of figuring out when you are at the end of the stream, rather than rolling your own counter with sizeof(int). Your method may not be precise enough, and the fact that you are using an unsafe code for that is also not too good.

One way probe if you are at the end of the stream or not is to use the PeekChar method:

while (br.PeekChar() != -1)
{
    // 3.
    // Read integer.
    int v = br.ReadInt32();
    textBox1.Text = v.ToString();
}

A more common solution is to write the number of ints that you are saving in a binary file in front of the actual list of integers. This way you know when to stop without relying on the length or the position of the stream.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • dasblinkenlight im getting the same error. I just updated my question with the code using your sample solution but im getting the same erorr exception. – Daniel Lip Aug 16 '12 at 02:40
  • @DanielLip I suspected that the method would not be reliable enough. Try the code from the update to see if it does any better, although it would fail if the number of bytes in your binary file is not divisible by the size of `Int32` on disk. – Sergey Kalinichenko Aug 16 '12 at 02:51
4

One reason your code could fail is if file contains extra bytes (i.e. 7 byte long file). Your code will trip on last 3 bytes.

To fix - consider computing number of integers in advance and using for to read:

var count = br.BaseStream.Length / sizeof(int);
for (var i = 0; i < count; i++)
{
  int v = br.ReadInt32();
  textBox1.Text = v.ToString();
}

Note that this code will simply ignore last 1-3 bytes if they are there.

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
  • Alexei Levenkov i tried your code and ended with the result: -1325399654 thats what i saw in the textBox1. Could be from a 200mb file ? – Daniel Lip Aug 16 '12 at 02:44
  • @DanielLip, What is wrong with -1325399654? What do you expect? It is kind of hard to argue if it any better or worse than 42 or 13. – Alexei Levenkov Aug 16 '12 at 02:46
  • Alexei i need to upack files from this giant 200mb file. Thats why i thought 200mb file size will give more numbers. But i guess you right i just dont know what to do next with this numbers i got. – Daniel Lip Aug 16 '12 at 02:50
1

The binary reader is not pointing to the start of the stream.

Use this code before reading the integer value:

br.BaseStream.Seek(0, SeekOrigin.Begin);
RobC
  • 22,977
  • 20
  • 73
  • 80