Solved

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

Posted on 2004-04-05
6
1,014 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
0
Comment
Question by:d2beetle
6 Comments
 
LVL 8

Expert Comment

by:nishikanth
ID: 10762431
catch (EndOfStreamException eof) {
            throw new ArgumentException("End of File.", eof);
   }

0
 
LVL 28

Expert Comment

by:iboutchkine
ID: 10762569
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
0
 

Author Comment

by:d2beetle
ID: 10762902
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)?
0
MIM Survival Guide for Service Desk Managers

Major incidents can send mastered service desk processes into disorder. Systems and tools produce the data needed to resolve these incidents, but your challenge is getting that information to the right people fast. Check out the Survival Guide and begin bringing order to chaos.

 
LVL 12

Expert Comment

by:dfiala13
ID: 10762988
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

0
 

Author Comment

by:d2beetle
ID: 10771516
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?
0
 
LVL 12

Accepted Solution

by:
dfiala13 earned 250 total points
ID: 10771541
I think it's pretty straightforward.  Here's the link from the MS Site on how it works.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemRuntimeSerializationFormattersBinaryBinaryFormatterClassSerializeTopic.asp

Just start small.  Serialize a single object and deserialize it.  Use the microsoft code as a starting point.  Add an object when you feel comfortable.  Once you figure out the second one, the rest will be easy.  I think the secret is to use collection classes (collections, hashtables) when you have multiple instances of the same type of object.
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Summary Displaying images in RichTextBox is a common requirement with limited solutions available. Pasting through clipboard or embedding into RTF content only support static images.  This article describes how to insert Windows control objects int…
Welcome my friends to the second instalment and follow-up to our Minify and Concatenate Your Scripts and Stylesheets (http://www.experts-exchange.com/Programming/Languages/.NET/ASP.NET/A_4334-Minify-and-Concatenate-Your-Scripts-and-Stylesheets.html)…

713 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question