反序列化要显示的文件中的对象列表

时间:2015-11-15 20:48:33

标签: .net vb.net binaryformatter

基本上我创建了一个文件来存储来自名为 TravelRecord 的对象的序列化数据。我没有问题序列化数据并使用 BinaryFormatter()将其存储在文件中,我没有问题检索第一条记录。我只想检索所有记录并在ListBox中显示它们。

以下是一些相关代码:

     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())

这适用于返回第一条记录,但我想让它返回所有这些记录,以便我可以像下面这样迭代它们:

 For Each r As TravelRecord In records
            RequestLst.Items.Add(r.ToString())
        Next

我知道我可能遗漏了一些非常简单的东西,但我尝试的所有内容都会导致RunTime错误。可能还有更好的方法来解决这个问题。

这是文件中序列化数据的样子。

  ÿÿÿÿ          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,Ô €ê¡}/Ô      `@

我的问题似乎是如何阅读所有这些并将它们变成一个集合,以便我可以使用它们。

以下是TravelRecord类的代码:

    <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

来自评论:

序列化代码:

formatter.Serialize(output, travelRequest) 

其中travelRequest是TravelRecord的一个实例。

我可能需要更好地解释这一切。该系统供用户提交TravelRecords。序列化设置为Append文件的新TravelRecord,就像数据库一样。 (这是我通常使用SQL的家庭作业)。反序列化是读取文件中的所有条目并将其显示在摘要ListBox中。

反序列化仅获得一个TravelRecord的原因是因为我不知道如何从文件中获取所有TravelRecords。

有没有办法计算序列化文件中有多少项,所以我可以做一个有限的For循环或其他什么

1 个答案:

答案 0 :(得分:2)

您一次只能写一条记录:

formatter.Serialize(output, travelRequest)

所以你必须一次读回一条记录。 BinaryFomratter存储类型数据和数据(TravelRecord),因此您无法将其作为集合(数组或List(of TravelRecord))读回来,因为它无法从一个类型转换为集合类型(没有一些旋转,我相信你不想进行)。你可以在文件中看到类型数据:

  

TravelRequest,Version = 1.0.0.0,Culture = neutral,PublicKeyToken ...

该文件不能随机访问,因此要获得记录3或找到“Foo”,您将不得不做类似的事情(例如,测试用户名=“Bob”和Exit For)。代表TravelRecord的是一个名为NVP的课程,我碰巧使用它。

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

用法和测试:

Dim mylist = GetListofTravelRecords()

For Each item In mylist
    Console.WriteLine(item.ToString)
Next

输出:

  

ziggy(1)
  zacky(2)
  zoey(3)
  ziggy(4)
  zacky(5)

我有11件东西,他们都以相同的顺序安全地回来了。

请注意其他人,serialize an entire collection更容易,并将作为集合读回来。