Serializing and Deserializing an array of collections
Serializing and Deserializing an array of collections
Serializing and Deserializing an array of collections
Serializing and Deserializing an array of collections
Serializing and Deserializing an array of collections
Serializing and Deserializing an array of collections Serializing and Deserializing an array of collections Serializing and Deserializing an array of collections Serializing and Deserializing an array of collections Serializing and Deserializing an array of collections Serializing and Deserializing an array of collections Serializing and Deserializing an array of collections Serializing and Deserializing an array of collections
Serializing and Deserializing an array of collections Serializing and Deserializing an array of collections
Serializing and Deserializing an array of collections
Go Back  Xtreme Visual Basic Talk > > > Serializing and Deserializing an array of collections


Reply
 
Thread Tools Display Modes
  #1  
Old 08-28-2011, 10:10 PM
SeahawkFan SeahawkFan is offline
Freshman
 
Join Date: Oct 2010
Location: Los Angeles, CA
Posts: 26
Default Serializing and Deserializing an array of collections


I'm developing a program that captures a bunch of information entered by a user on a tab form into five different structured arrays. I want the data to be saved into a single file and reloaded by the program into a similarly built series of structured arrays through a different form.

If I understand the process of serializing collections right, I create a single ArrayList variable to capture each of the five Structured arrays. Here they are:

Code:
    Structure RosterDesc
        Public rostName As String
        Public rostMin As String
        Public rostMax As String
        Public rostUnit As String
    End Structure

    Structure StatSum
        Public Stat, Unit As String
    End Structure

    Structure StatArray
        Public Stat As String
        Public Unit As String
    End Structure

    Structure UnitArray
        Public Name As String
        Public Choice As Integer
    End Structure

    Structure WeapArray
        Public Name As String
        Public Choice As Integer
    End Structure

    Structure SpecialArray
        Public Name As String
        Public Desc As String
    End Structure

    Public RostEntry(8) As RosterDesc
    Public Summary(3, 9) As StatSum
    Public UnitList(2) As String
    Public UnitTypes(32) As UnitArray
    Public WeapTypes(31) As WeapArray
    Public SpecialTypes(99) As SpecialArray

<program>

<save button Sub>
    Dim Rules as New ArrayList()
    Rules.Add(RostEntry)
    Rules.Add(StatSum)
    Rules.Add(UnitList)
    Rules.Add(UnitTypes)
    Rules.Add(WeapTypes)
    Rules.Add(SpecialTypes)

    Dim saveFile as FileStream
    saveFile = File.OpenWrite("C:\Rules.bin")
    saveFile.Seek(0, SeekOrigin.End)
    Dim Bformatter As BinaryFormatter = New BinaryFormatter()
    Bformatter.Serialize(saveFile, Rules)
    saveFile.Close()
    MsgBox("ArrayList serialized successfully")
<end save Sub>
When reading the section on deserializing, it states that I create a readFile FileStream, open and read the bin file, establish a new ArrayList with the same name as the previous ArrayList (Rules), but this is the confusing part I don't understand.

It says to declare one variable as the same type as the first variable type in the Rules ArrayList, but nowhere does the rest of the procedure mention anything about this new variable being used.

Here's the load sub write-up to elaborate:

Code:
Dim readFile As FileStream
readFile = File.OpenRead("C:\Rules.bin")
Dim BFormatter As BinaryFormatter()
Dim Rules As New ArrayList()
Dim R1 As Rectangle [in the example, the first element in ArrayList is R1, a Rectangle variable]
Rules = CType(BFormatter.Deserialize(readFile), ArrayList)
Dim i As Integer
TextBox1.AppendText("The ArrayList contains " & Rules.Count & _
      " objects " & vbCrLf & vbCrLf)
For i = 0 To Rules.Count - 1
    TextBox1.AppendText(Rules(i).ToString & vbCrLf)
Next
End Sub
As you can see, R1 never comes up.

Several questions:

1. Do I have to declare one variable of the same type as the one in the first element of the ArrayList, or does having the public variable declared in the Class that's going to take this information already cover that?

2. Once I deserialize into the newly declared Rules ArrayList in the new form, is it a simple matter of setting the duplicated variables in the new form equal to the relevant element in the ArrayList? For example, if I have a new Public Roster As RosterDesc variable declared, can I set it equal to Rules(0) and it would automatically populate every element in the same order as they were created in the original form?

Apologies if this is covered elsewhere. I tried searching the site for hints but couldn't get any outright answers.
Reply With Quote
  #2  
Old 08-29-2011, 04:55 AM
PlausiblyDamp's Avatar
PlausiblyDampSerializing and Deserializing an array of collections PlausiblyDamp is offline
Ultimate Contributor

Forum Leader
* Expert *
 
Join Date: Nov 2003
Location: Newport, Wales
Posts: 2,058
Default

You could do without the ArrayList and simply serialize the five entries one after the other to the FileStream, when deserializing you would just need to read out the five items in the same order you serialized them.
__________________
Intellectuals solve problems; geniuses prevent them.
-- Albert Einstein

Posting Guidelines Forum Rules Use the code tags
Reply With Quote
  #3  
Old 08-29-2011, 09:40 AM
SeahawkFan SeahawkFan is offline
Freshman
 
Join Date: Oct 2010
Location: Los Angeles, CA
Posts: 26
Default

Would I need to keep track of positions where one entry ends and the next begins, or does the system intuitively understand where they end and begin as I deserialize automatically (as long as my order, structure setups and variables are identical)?
Reply With Quote
  #4  
Old 08-29-2011, 09:49 AM
AtmaWeapon's Avatar
AtmaWeaponSerializing and Deserializing an array of collections AtmaWeapon is offline
Fabulous Florist

Forum Leader
* Guru *
 
Join Date: Feb 2004
Location: Austin, TX
Posts: 9,500
Default

IMO serialization is a false promise. People who either don't know better or forget the pitfalls tell newbies it's the easy one-line way to save something to a file. Here's the circumstances in which that is true:
  • You want to save one object.
  • If you are saving a collection (a collection is an object), it is a collection of one type.
  • The object has nothing but public properties.
  • You own the object.
  • You will never change the object.

You're in a case where you want to save 5 objects. That means you just made serialization about as complicated as writing your own file format (which isn't hard.) Note I'm not calling it impossible. It's possible and I've done it. But in my opinion it's equivalent effort to saving things yourself and if you do it yourself it's easier to customize it to your needs.

ArrayList is ancient and reviled by modern .NET programmers. Any time you see a code sample that uses it, ask yourself why it's there and if it's really needed. In this case, it's used because if a List(Of T) were used you couldn't cram one of each kind of object into it. So instead of the simple case, you get to create a list of all of the objects, then write code to pick them out, test type, find the right array, etc.

If you still want to use serialization, you can do so with a quick modification. Look back at the rules that make it an "easy" scenario. It's best if you're saving a collection of one type. What if you make a type that contains one of each of the five objects?
Code:
<Serializable()>
Class SerializationPackage
    Public roster As RosterDesc
    Public statSum As StatSum
    ...
End Class
Now when you want to save everything, create a list of that type and package everything up. Here's a guess at what it might look like; any variable named with a $ is one I made up:
Code:
Dim serializationList As New List(Of SerializationPackage)()
For i As Integer = 0 To $something
    Dim packageItem As New SerializationPackage()
    packageItem.roster = $rosters(i)
    ...
    serializationList.Add(packageItem)
Next

Using fs As Stream = File.OpenWrite($blah)
    Dim serializer As New BinaryFormatter()
    serializer.Serialize(fs, serializationList)
End Using
Reading it back's a snap; you can keep the package around for convenience or push the objects back out to their arrays:
Code:
Dim serializationList As List(Of SerializationPackage)()
Using fs As Stream = File.OpenRead($blah)
    Dim serializer As New BinaryFormatter()
    Dim rawObject As Object = serializer.Deserialize(fs)
    serializationList = CType(rawObject, List(Of SerializationPackage))
End Using

' Presuming lists instead of arrays; much cleaner
For Each serializedItem In serializationList
    $rosters.Add(serializedItem.roster)
    ...
Next
Personally I think the SerializationPackage object might belong as the only collection you need, and I don't like .NET serialization, but this is a more or less quick fix to your problem.

With respect to serializing each array as PD pointed out, part of serializing arrays is storing their index so the deserializer knows when to stop looking for data. So yes, the system will magically remember how big the array was. I don't like that technique as much because it requires more thought than writing out one object.
__________________
.NET Resources
My FAQ threads | Tutor's Corner | Code Library
I would bet money 2/3 of .NET questions are already answered in one of these three places.
Reply With Quote
  #5  
Old 08-29-2011, 10:30 AM
SeahawkFan SeahawkFan is offline
Freshman
 
Join Date: Oct 2010
Location: Los Angeles, CA
Posts: 26
Default

I haven't actually programmed anything. I'm just trying to wrap my head around the best way to save my information and read it back. Based on what I was reading through my manual, I was given the impression that the best way to save structured objects to a file was via serialization.

You mentioned that you don't like .NET serialization. What would be your preferred method to save collections as I have them? BinaryWriter/Reader, StreamWriter/Reader or something else entirely? I discounted these two options since the examples provided in my manual were simpler than what I'm using (StreamWriter/Reader) or have no examples at all (BinaryWriter/Reader), and the only mention of collections occurs in the Serialization section.

And before I forget, thank you both for responding and helping me understand this material better. It's greatly appreciated!
Reply With Quote
  #6  
Old 08-29-2011, 06:26 PM
AtmaWeapon's Avatar
AtmaWeaponSerializing and Deserializing an array of collections AtmaWeapon is offline
Fabulous Florist

Forum Leader
* Guru *
 
Join Date: Feb 2004
Location: Austin, TX
Posts: 9,500
Default

Your manual (and many others) won't tell you the most important thing: there is rarely a "best" way to do common tasks in programming.

In this case, each technique has a tradeoff:
  • .NET binary serialization is easy if you follow the rules. But you have little control over the format. If your file gets corrupted, it's hard to fix. It's not so useful for communication between applications because the type has to be in a DLL both applications reference, and if the versions are out of sync it just won't work.
  • .NET XML serialization is easy if you follow the rules. You have a tiny bit of control over the format. If the file gets corrupted, with some observation skills you can work out how to repair it. The same communication restrictions apply as with binary serialization.
  • Writing your own serialization requires some planning, knowledge, and effort. But you fully control the format. You can introduce error correction and sometimes write tools to deal with corrupted files. It can be useful for communication between arbitrary applications because only the file format is contract: the applications can use different objects and even ignore some of the file's data. You can handle your own versioning.
It's all a matter of what you hold important when writing your program. .NET serialization's usually not much effort, but you give up a lot of power. Sometimes the need for customization warrants the extra work to write your own file. Since most of the applications I write need their file formats documented and they might be consumed by future programs in different languages, I prefer to write my own.
__________________
.NET Resources
My FAQ threads | Tutor's Corner | Code Library
I would bet money 2/3 of .NET questions are already answered in one of these three places.
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
Serializing and Deserializing an array of collections
Serializing and Deserializing an array of collections
Serializing and Deserializing an array of collections Serializing and Deserializing an array of collections
Serializing and Deserializing an array of collections
Serializing and Deserializing an array of collections
Serializing and Deserializing an array of collections Serializing and Deserializing an array of collections Serializing and Deserializing an array of collections Serializing and Deserializing an array of collections Serializing and Deserializing an array of collections Serializing and Deserializing an array of collections Serializing and Deserializing an array of collections
Serializing and Deserializing an array of collections
Serializing and Deserializing an array of collections
 
Serializing and Deserializing an array of collections
Serializing and Deserializing an array of collections
 
-->