如何在.exe关闭后在vb.net中保存/重新加载数据?

时间:2014-05-14 14:11:18

标签: vb.net save

我是vb.net的新手,这是我的第一个项目,我相当确定有一个我无法找到的明显答案。

问题:我有一个我用许多属性定义的结构列表。我希望能够在关闭程序并加载备份之后,使用我保存到的值来编辑和加载该列表。做这个的最好方式是什么?

这不是一个简单的字符串或bool,否则我会在项目的属性中使用通常建议的用户设置。我已经看到其他人将它保存为xml并将其恢复原状,但我并不倾向于这样做,因为这将分发给其他人。由于它是一个复杂的结构,通常持有的首选方法是什么?

示例

这是一个结构:

Structure animal
 Dim coloring as string 
 Dim vaccinesUpToDate as Boolean
 Dim species as string 
 Dim age as integer 
End structure 

并且用户将添加的列表(动物)说1只猫,2只狗等。我想要它,以便在用户添加这些程序后关闭程序,该结构将被保存仍然有那只1只猫和2只狗的设置,所以我可以再次显示它们。在我的程序中保存数据的最佳方法是什么? 谢谢!

1 个答案:

答案 0 :(得分:2)

考虑序列化。为此,一个类比旧式的Struct更有序:

<Serializable>
Class Animal
    Public Property Name As String
    Public Property Coloring As String
    Public Property VaccinesUpToDate As Boolean
    Public Property Species As String   
    Public Property DateOfBirth As DateTime

    Public ReadOnly Property Age As Integer
        Get
            If DateOfBirth <> DateTime.MinValue Then
                Return (DateTime.Now.Year - DateOfBirth.Year)
            Else
                Return 0   ' unknown
            End If
    End Get
    End Property

    ' many serializers require a simple CTor
    Public Sub New()

    End Sub

    Public Overrides Function ToString() As String
        Return String.Format("{0} ({1}, {2})", Name, Species, Age)
    End Function
End Class

ToString()覆盖可能很重要。如果您将Animal个对象添加到ListBox,例如:“Stripe(Gremlin,27)”

,它将显示的内容
Friend animalList As New List(of Animal)   ' a place to store animals

' create an animal
a = New Animal
a.Coloring = "Orange"
a.Species = "Feline"       ' should be an Enum maybe
a.Name = "Ziggy"
a.BirthDate = #2/11/2010#

animalList.Add(a)
' animalList(0) is now the Ziggy record. add as many as you like.

在更复杂的应用中,您可以编写一个Animals集合类。在这种情况下,List可能是内部的,集合可以保存/加载列表。

Friend Sub SaveData(fileName as String)
    Using fs As New System.IO.FileStream(fileName,
        IO.FileMode.OpenOrCreate)

        Dim bf As New BinaryFormatter
        bf.Serialize(fs, animalList)
   End Using
End Sub

Friend Function LoadData(fileName as String) As List(Of Animal)
     Dim a As List(of Animal)
     Using fs As New FileStream(fileName, FileMode.Open, FileAccess.Read)
        Dim bf As New BinaryFormatter
        a = CType(bf.Deserialize(fs), List(Of Animal))
    End Using
    Return a
End Function

XMLSerialization,ProtoBuf甚至json都是相同的语法。对于少量数据,序列化列表是数据库的简单替代(并且具有许多其他用途,例如更好的设置方法)。

计算字段为属性

请注意,我添加了BirthDate属性并更改了Age来计算结果。您不应保存任何可以轻松计算的内容:为了更新Age(或VaccinesUpToDate)您必须“访问”每条记录,执行计算然后保存结果 - 可能在24小时内出错了。

Age作为属性(而不是函数)公开的原因用于数据绑定。将List<T>用作DataSource

是很常见的
animalsDGV.DataSource = myAnimals

每个动物的结果将是一行,每个属性作为一列。原始Fields中的Structure将不会显示。也不会显示Age()函数,将结果包装为只读属性会显示它。在PropertyGrid中,它会显示为已停用,因为它是RO。

班级与结构

因此,如果使用Properties的Structure可以工作,为什么要使用Class呢?从Choosing Between Class and Struct on MSDN开始,避免使用结构,除非该类型符合以下所有条件:

  1. 它逻辑上表示单个值,类似于原始类型(int,double等)
  2. 实例大小小于16字节
  3. 这是不可改变的
  4. 不必频繁装箱
  5. Animal未通过前3个点(虽然它是本地,但它不是#1)。它可能也会失败,取决于它的使用方式。