Reputation: 110
Basically I have created a file that I store serialized data from an Object called TravelRecord. I have no issue serializing the data and storing it in the file using a BinaryFormatter(), and I have no issue retrieving the first record. I just want to retrieve all the records and display them in a ListBox.
Here's some of the relevant code:
Private reader As New BinaryFormatter()
Private input As FileStream
input = New FileStream(fileName, FileMode.Open, FileAccess.Read)
Dim record = CType(reader.Deserialize(input), TravelRecord)
RequestLst.items.Add(record.toString())
This works for returning the first record, but I want it to return all of them so I can iterate through them like the following:
For Each r As TravelRecord In records
RequestLst.Items.Add(r.ToString())
Next
I know I'm probably missing something really simple, but everything I try causes RunTime errors. There may also be a better way to handle this.
Here is what the serialized data in the file looks like.
ÿÿÿÿ DTravelRequest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null TravelRequest.TravelRecord ID FirstNameLastNamePurpose StartDateEndDateAmount System.Guid
ýÿÿÿSystem.Guid _a_b_c_d_e_f_g_h_i_j_k “ŸPªO½cùømFÚw Steve Robinson Semianr U¾Ó €æ©PÓ @o@ @_@ ÿÿÿÿ DTravelRequest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null TravelRequest.TravelRecord ID FirstNameLastNamePurpose StartDateEndDateAmount System.Guid
ýÿÿÿSystem.Guid _a_b_c_d_e_f_g_h_i_j_k æ;o˜ùéAÎÜ^pñÌ jake Kirkbride Stuff l«™ Ó €CøX,Ô À^@ ÿÿÿÿ DTravelRequest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null TravelRequest.TravelRecord ID FirstNameLastNamePurpose StartDateEndDateAmount System.Guid
ýÿÿÿSystem.Guid _a_b_c_d_e_f_g_h_i_j_k FP“¼Î«Gž¥5tuUš steve stevenson vacation @áw%Ó @ˆ!?(Ó @_@ ÿÿÿÿ DTravelRequest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null TravelRequest.TravelRecord ID FirstNameLastNamePurpose StartDateEndDateAmount System.Guid
ýÿÿÿSystem.Guid _a_b_c_d_e_f_g_h_i_j_k ‹MÆoh#D–âÑQþ…P Steve Stevenson Program €œN4)Ô €CøX,Ô @_@ ÿÿÿÿ DTravelRequest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null TravelRequest.TravelRecord ID FirstNameLastNamePurpose StartDateEndDateAmount System.Guid
ýÿÿÿSystem.Guid _a_b_c_d_e_f_g_h_i_j_k k$ˆµ§FŠm§Íüâ George Govern Stuff €CøX,Ô €ê¡}/Ô `@
It seems my issue is how do I read all of these and turn them into a collection so I can work with them.
Here is the code for the TravelRecord Class:
<Serializable()>
Public Class TravelRecord
'Class fields
Public ID As Guid
Public FirstName As String
Public LastName As String
Public Purpose As String
Public StartDate As Date
Public EndDate As Date
Public Amount As Double
Public Sub New()
MyClass.New(Guid.Empty, String.Empty, String.Empty, String.Empty,
Nothing, Nothing, 0.0)
End Sub
Public Sub New(id As Guid, fName As String, lName As String,
purpose As String, startDate As Date, endDate As Date,
amount As Double)
MyClass.ID = id
MyClass.FirstName = fName
MyClass.LastName = lName
MyClass.Purpose = purpose
MyClass.StartDate = startDate
MyClass.EndDate = endDate
MyClass.Amount = amount
End Sub
Public Overrides Function ToString() As String
Return String.Format("{0,-40}{1,-10}{2,-10}{3,-15}{4,12:d}{5,12:d}{6,12:C}", _
ID, FirstName, LastName, Purpose, StartDate, EndDate, Amount)
End Function
End Class
From comments:
The serialization code:
formatter.Serialize(output, travelRequest)
Where travelRequest is an instance of TravelRecord.
I might need to explain this better is all. The system is for a User to submit TravelRecords. The Serialization is setup to Append
a new TravelRecord to the file to act as like a database. (This is a homework assignment I usually use SQL). The Deserialization is to read all of the entries in the File and display them in a summary ListBox.
The reason Deserialization is only getting one TravelRecord is because I don't know how to get all the TravelRecords out of the File.
Is there a way to get a count of how many items are in the serialized file so I can do a finite For loop or something
Upvotes: 1
Views: 728
Reputation: 38875
You write one record at a time:
formatter.Serialize(output, travelRequest)
so you will have to read back one record at a time. The BinaryFomratter
stores Type data along with the data (TravelRecord
) so you cant just read it back as a collection (array or List(of TravelRecord)
because there is no way it can convert from one Type to a collection Type (without some gyrations I am sure you dont want to undertake). You can see the Type data in the file:
TravelRequest, Version=1.0.0.0, Culture=neutral, PublicKeyToken...
The file wont be random access, so to get record 3 or find "Foo" you will have to do something similar (eg test for username = "Bob" and Exit For
). Standing in for TravelRecord
is a class named NVP which I happen to have handy.
Function GetListofTravelRecords() As List(Of NVP)
Dim tmpList As New List(Of NVP)
Dim tmp As NVP
Using fs As New FileStream("C:\Temp\nvplst.bin", FileMode.Open)
Dim bf As New BinaryFormatter
Do Until fs.Position >= fs.Length
tmp = CType(bf.Deserialize(fs), NVP)
tmpList.Add(tmp)
Loop
End Using
Return tmpList
End Function
Usage and test:
Dim mylist = GetListofTravelRecords()
For Each item In mylist
Console.WriteLine(item.ToString)
Next
Output:
ziggy (1)
zacky (2)
zoey (3)
ziggy (4)
zacky (5)
I had 11 things in there and they all made it back safely and in the same order.
Note to others, it is much easier to serialize an entire collection and read it back as collection.
Upvotes: 2