如何保存阵列?

时间:2015-10-29 13:35:47

标签: arrays vb.net save

我有一个包含用户名的数组。这就是它的样子:

dim numberofaccounts as integer
dim username(numberofaccounts) as string

我想将这些数据存储在某处,所以当我重新打开它时,它将拥有所有信息。我已经厌倦了使用" My.Settings.usernames"但它无法容纳数组。

我当时认为可以使用word文档来保存这些信息。我知道如何编写它以及如何阅读有关单词doc的信息,但它作为一条信息出来,例如:大卫,丹,弗雷德,。不是3比特的信息。

将有大约100个帐户

2 个答案:

答案 0 :(得分:3)

正如Plutonix所提到的,有一种特殊类型的字符串数组可以与My.Settings一起使用。它被称为StringCollection

请参阅here

转到项目属性并添加StringCollection类型的新设置(将值保留为空白)。

在您的代码中,您可以按如下方式创建和访问值:

My.Settings.UserNames = New Specialized.StringCollection()
My.Settings.UserNames.Add("User 1")
My.Settings.Save()

正如其他人所提到的,这可能不是存储用户名的好方法,尤其是在用户数量很大的情况下。

答案 1 :(得分:1)

在此实例中使用My.Settings不是最佳解决方案。虽然是,.NET将负责保存数据并为您加载,My.Settings中的数据是不稳定的。如果您的应用程序编译为ManagedCode(大多数.NET代码都可以),则My.Settings项与应用程序的Assembly版本相关联。如果更改程序集的版本,则会丢失My.Settings中存储的数据,因为.NET代码会将程序集视为一个全新的应用程序。此外,如果从不同的路径移动并执行.exe文件,则设置也将丢失,因为.NET将查看应用程序和完全不同的实例。

更好的选择是自己保存数据。您可以通过序列化对象并将其保存到文件来完成此操作。反序列化文件时,返回将是保存的完全相同的对象。我建议创建一个类,它是数组的包装器,甚至更好List(Of String)。以下是一个示例控制台应用程序,用作参考:

' Always, always, always use these (unless you have a few edge cases, usually reflection)
Option Strict On
Option Explicit On

' Makes for shorter code
Imports System.Runtime

Module Module1
    Sub Main()
        ' File path to save the file, hardcoded here just for an example
        Dim filePath As String = "C:\StackOverflow\usernames.dat"
        ' Set it to Nothing to prove that the below methods work, if they don't you'll get an NRE
        Dim userNames As UsernameWrapper = Nothing

        Console.Write("do you want to read from the file or write to a file? [r / w] ")
        If Console.ReadKey.Key = ConsoleKey.W Then
            Console.WriteLine() : Console.WriteLine("Enter three usernames:")
            ' Create the object that we want to save
            userNames = New UsernameWrapper({Console.ReadLine, Console.ReadLine, Console.ReadLine})
            'Save the object to a file
            userNames.SaveToFile(filePath)
        Else
            ' Get the object from the file
            userNames = UsernameWrapper.ReadFromFile(filePath)
            Console.WriteLine() : Console.WriteLine("Saved usernames loaded from file:")
            ' Output the contents
            userNames.UserNames.ForEach(Sub(x) Console.Write(x & " ")) : Console.WriteLine()
        End If


        Console.WriteLine()
        Console.Write("Run Again? [y / n] ")
        If Console.ReadKey.Key = ConsoleKey.Y Then
            Console.WriteLine() : Console.WriteLine()
            ' Set it to nothing to prove that the above methods are working,
            ' if they didn't work you'd get a NRE on next run
            userNames = Nothing
            ' Call Main() again for a new run
            Main()
        End If

    End Sub

End Module


' This is the key to the whole thing, this attribute is what allows the object to be serialized
<Serializable()>
Public Class UsernameWrapper
    Public Property UserNames As List(Of String)

    ' Just a few ways of instantiating the object
    Public Sub New()
        Me.UserNames = New List(Of String)
    End Sub
    Public Sub New(ByVal usernameArray() As String)
        Me.UserNames = usernameArray.ToList()
    End Sub

    Public Sub New(ByVal userNameList As List(Of String))
        Me.UserNames = userNameList
    End Sub

    ''' <summary>
    ''' Save the current object to a file
    ''' </summary>
    ''' <param name="filePath">Path to save the file to</param>
    ''' <remarks>http://stackoverflow.com/users/2659234</remarks>
    Public Sub SaveToFile(ByVal filePath As String)
        ' Create the formatter that will do the serialization
        Dim formatter As Serialization.IFormatter = New Serialization.Formatters.Binary.BinaryFormatter()
        Using fs As New IO.FileStream(filePath, IO.FileMode.Create, IO.FileAccess.Write)
            ' Serialize the data
            formatter.Serialize(fs, Me)
        End Using
    End Sub

    ''' <summary>
    ''' Load object from file
    ''' </summary>
    ''' <param name="filePath">Path of the file to read from</param>
    ''' <returns>The deseerailized object</returns>
    ''' <remarks>http://stackoverflow.com/users/2659234</remarks>
    Public Shared Function ReadFromFile(ByVal filePath As String) As UsernameWrapper
        ' Create the formatter that will do the serialization
        Dim formatter As Serialization.IFormatter = New Serialization.Formatters.Binary.BinaryFormatter()
        ' The deserialized object will be saved to this
        Dim _usernameWrapper As UsernameWrapper = Nothing

        Using fs As New IO.FileStream(filePath, IO.FileMode.Open, IO.FileAccess.Read)
            ' Deserialize the object and cast it to the correct type
            _usernameWrapper = TryCast(formatter.Deserialize(fs), UsernameWrapper)
        End Using

        ' If the deserializing failed, throw an error
        If IsNothing(_usernameWrapper) Then Throw New Runtime.Serialization.SerializationException(String.Format("Could not deserialize {0}.", filePath))

        Return _usernameWrapper
    End Function
End Class