Search code examples
arraysvb.netserializationstructurerecord

Trying to save an array of structures to file and load from file (serialize, deserialize)


Here is my array:

    Public RacersArray(AmountOfRacers - 1) As Racer

<Serializable()> Public Structure Racer
    Public Name As String
    Public CleatSize As String
    Public SkillLevel As String
    Public Height As String
    Public Team As String
    Public CompatibilityArr() As String
End Structure

<Serializable()> Public Structure Compatibility
    Public Name As String
    Public Score As Integer
End Structure

Below is the code I am using to try save and load from file. The file is getting populated with what looks like the correct gibberish, but when loading the array and it's indexes are still 'nothing'

    Public Sub RacersInputSAVE()
    Dim bf As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
    Dim fStream As New FileStream(SaveLocation, FileMode.Create)

    bf.Serialize(fStream, InputRacers.RacersArray) ' write to file

    fStream.Close()
End Sub

Public Sub RacersInputLOAD()
    Dim bf As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
    Dim fStream As New FileStream(LoadLocation, FileMode.Open)

    InputRacers.RacersArray = bf.Deserialize(fStream) ' read from file

    fStream.Close()
End Sub

Solution

  • The first thing that is probably wrong is this:

    Public CompatibilityArr() As String
    

    Based on the names it seems like that is supposed to be that second Compatibility structure. If so, it should be:

    Public CompatibilityArr As Compatibility()
    

    Its not clear if that is part of the problem being described (but when loading the array and it's indexes are still 'nothing' is vague since there is more than one array). Otherwise the second structure isnt being used.

    Next, set Option Strict On. When deserializing, the BinaryFormatter always returns Object which needs to be cast to the correct Type:

    Racers = DirectCast(bf.Deserialize(fs), Racer()) ' read from file
    

    With those 2 changes, all the data made the round trip fine for me.

    Third, Structure is not the right Type for that. Those should be classes, and rather than public Fields/Members, use Properties especially if there will be any data binding involved:

    <Serializable()> 
    Public Class Racer
        Public Property Name As String
        ...
    

    Also, anything which implements a Dispose()method, like a FileStream should be used in a Using block which will close and dispose of the target object:

    Dim bf As New BinaryFormatter
    Using fs As New FileStream(fileName, FileMode.Create)
        bf.Serialize(fs, Racers) ' write to file
    End Using
    

    Finally, you would probably find some of the NET collections such as List(Of Racer) to be easier to work with than arrays. It takes about 15 mins to learn how they work.

    MSDN: Choosing Between Class and Struct