We help IT Professionals succeed at work.

Check out our new AWS podcast with Certified Expert, Phil Phillips! Listen to "How to Execute a Seamless AWS Migration" on EE or on your favorite podcast platform. Listen Now

x

How do you check for EOF when using FileStream, Serialization and Binary Files?

Frank Bryant
Frank Bryant asked
on
Medium Priority
1,056 Views
Last Modified: 2011-10-03
I'm a Newbie + 1 (I've ask one question already); I want to display all data lines read from a binary file in a multi-line text box.  How do you check for EOF in a DO/LOOP when using FileStream, Serialization and Binary Files? Below is the code that I am attempting to use:

Private Sub btnRead_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRead.Click
    Dim SerialObj As SalesData
    Dim f As Formatters.Binary.BinaryFormatter
    Dim s As Stream

    Try
        SerialObj = New SalesData(Me.txtCustomerName.Text, Me.txtProductDescription.Text, Me.txtQuantity.Text, Me.txtSalesTotal.Text, Me.txtSalesDate.Text)
        f = New Formatters.Binary.BinaryFormatter
        s = New FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.None)
        SerialObj = f.Deserialize(s)

      'This DO/LOOP does not work.
       Do While s.Seek <> -1
            'Read data lines and display them in a Mulit-Line Text box.
            txtReadLines.Text = SerialObj.fCustomerName & vbCrLf & SerialObj.fProductDescription & vbCrLf & SerialObj.fquantity & vbCrLf & SerialObj.fSalesTotal & vbCrLf & SerialObj.fSalesDate & vbCrLf
        Loop

        Refresh()
        s.Close()
        btnRead.Enabled() = False
        btnExit.Focus()

    Catch ex As Exception
        'Catch Exception Errors
        MsgBox(ex.Message + Chr(13) + Chr(10) + Chr(10) + "File not found.")
    End Try

    'Set focus to the multi-line text box
    txtReadLines.Focus()
    txtReadLines.SelectAll()
End Sub
Comment
Watch Question

catch (EndOfStreamException eof) {
            throw new ArgumentException("End of File.", eof);
   }

In Visual Basic .NET you read a text file by first opening a StreamReader on it, and then iterating over all its
 lines until its Peek method returns -1 (which means EOF)

Imports System.IO

Dim sr As New StreamReader("c:\autoexec.bat")

' Display all the text lines in the file.
Do Until sr.Peek = -1
    ' The ReadLine methods reads whole lines.
    Console.WriteLine(sr.ReadLine)
Loop
' Always close a StreamReader when you've done with it.
sr.Close()

You can also read one character at a time with using the Read method, or you can read all the remaining
characters withusing the ReadToEnd method. For example, this routine returns the entire contents of any
text file in one operation:
Function ReadTextFile(ByVal filename As String) As String
    Dim sr As New StreamReader(filename)
    ReadTextFile = sr.ReadToEnd()
    sr.Close()
End Function

Author

Commented:
I have successfully done this using streamreader and streamwriter in previous code working with ASCII text files. My coding attempt this time is to use FileStream for writing object data to binary files; I then want to retrieve that object data and then display it in a multi-line text box. If I remove the DO/LOOP I can successfully display the data for one object line. It looks like this:

phil
jumper cables
1
15
4/5/2004

This is what I want to see:
phil <data record starts here>
<data>
<data>
<data>
<data>

<next record should start here>
<data>
<etc ...>

Am I asking the right question(s)?

Commented:
The deserialize method is called once for a supplied file, you don't read through it. The stream is converted in one call -- you don't read through it for each object.  If you want to do that, you can do your own custom file reads, the BinaryFormatter is supposed to save you from that problem.

Here's an example from microsoft, that converts the stream into a hashtable containing three strings.

Sub Deserialize()
        ' Declare the hashtable reference.
        Dim addresses As Hashtable = Nothing

        ' Open the file containing the data that you want to deserialize.
        Dim fs As New FileStream("DataFile.dat", FileMode.Open)
        Try
            Dim formatter As New BinaryFormatter

            ' Deserialize the hashtable from the file and
            ' assign the reference to the local variable.
            addresses = DirectCast(formatter.Deserialize(fs), Hashtable)
        Catch e As SerializationException
            Console.WriteLine("Failed to deserialize. Reason: " & e.Message)
            Throw
        Finally
            fs.Close()
        End Try

        ' To prove that the table deserialized correctly,
        ' display the key/value pairs.
        Dim de As DictionaryEntry
        For Each de In addresses
            Console.WriteLine("{0} lives at {1}.", de.Key, de.Value)
        Next
    End Sub

You can do the same thing for your objects.

Fill a collection or Hashtable with them.  Serialize the hashtable using the BinaryFormatter.Serialize method.

Then reconstruct the hashtable using the DirectCase of the deserialized stream
Dim yourobjects as Hashtable
 yourobjects = DirectCast(formatter.Deserialize(fs), Hashtable)
Then read them out one-by-one

 Dim de As DictionaryEntry
 Dim obj as SalesData
  For Each de In yourobjects
            obj = CType(de.Value, SerialObj)
          Debug.WriteLine(obj.fProductDescription)
   Next

Author

Commented:
dfiala13,

Thanks for your reply, but I beleive that I may be in a little to deep at this point. If I wanted to do what you suggest and create my own file reads, how would I go about doing it or should I just swim for the shore now?
Commented:
Unlock this solution and get a sample of our free trial.
(No credit card required)
UNLOCK SOLUTION
Unlock the solution to this question.
Thanks for using Experts Exchange.

Please provide your email to receive a sample view!

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.