I'm building an application that has its data on a custom data structure array with multiple variables and child arrays of other custom structures...
I need to be able to save and load that data to file and Serialization did work untill I needed to load and save that same file on multiple applications.
I had to use old VB6 technique to reach my goal. Is there a way to write this in more recent code?
On the examples below, Persons is an array of a structure containing all sorts of info on persons, including sub arrays of other structures of different sizes for their kids, pets, etc.
Save code:
'// Get file number
Dim fn As Integer = FreeFile()
'// Opens the file for binary write
FileOpen(fn, FileName, OpenMode.Binary, OpenAccess.Write)
'// Get persons count
Dim pc As Integer = Persons.GetUpperBound(0)
'// Write persons count
FilePut(fn, pc)
'// Write Persons
FilePut(fn, Persons)
'// Close the file
FileClose(fn)
Load code:
'// Get file number
Dim fn As Integer = FreeFile()
'// Opens the file for binary read
FileOpen(fn, FileName, OpenMode.Binary, OpenAccess.Read)
'// Get persons count
Dim pc As Integer
'// Read persons count
FileGet(fn, pc)
'// Prepare Persons array for it
Persons = Nothing
ReDim Persons(0 To pc)
'// Read Persons
FileGet(fn, Persons)
'// Close the file
FileClose(fn)
EDIT with additional information:
When using serialization this was that I was using. I've simplified things to make it easier to reproduce without exposing excessive info. Here's an example of 2 applications I've written as testing.
My structures and variable are as below. Each parent may have 0 or more kids:
'// Parent structure
<Serializable> Private Structure Parents
Dim Name As String
Dim Age As Integer
Dim Kids() As Kids
End Structure
'// Kid structure
<Serializable> Private Structure Kids
Dim Name As String
Dim Age As Integer
Dim GoesInScool As Boolean
End Structure
Private Persons() As Parents
To save I'm using this code:
'// Gets BinaryFormatter
Dim BF As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter()
'// Makes new Memorystream
Dim MS As New System.IO.MemoryStream()
'// Serialize to Memorystream
BF.Serialize(MS, Persons)
'// Writes the content to file
My.Computer.FileSystem.WriteAllBytes(FileName, MS.GetBuffer(), False)
To load I'm using this code:
'// Loads file to a byte()
Dim bytes As Byte() = My.Computer.FileSystem.ReadAllBytes(FileName)
'// Gets BinaryFormatter
Dim BF As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter()
'// Reads data
Persons = DirectCast(BF.Deserialize(New System.IO.MemoryStream(bytes)), Parents())
I've made 2 applications: StructureSaver_App_A and StructureSaver_App_B. They were made from scratch but I've copied exactly the same code on all functions.
When I save on StructureSaver_App_A and try to load on StructureSaver_App_B I get this error code: System.Runtime.Serialization.SerializationException: 'Unable to find assembly 'StructureSaver_App_A, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.'
When I save on StructureSaver_App_B and try to load on StructureSaver_App_A I get this error code: System.Runtime.Serialization.SerializationException: 'Unable to find assembly 'StructureSaver_App_B, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.'
Loading on StructureSaver_App_A a file saved on StructureSaver_App_A works perfectly fine. Loading on StructureSaver_App_B a file saved on StructureSaver_App_B works perfectly fine.
Thanks
You try to serialize an object from one application and deserialize it from another. Even when those objects seem to be the same, because of the same properties etc, they are not. Because they are in different assemblies or namespaces.
As you said you are serializing an object of type ApplicationOne.MyObject and deserialize it as ApplicationTwo.MyObject. The binary formatter will fail because within that binary data there is the name of the original type and this cannot be found as you are in a different context where this type does not exist. You need to extract those shared classes in an extra library and share it between your applications by referencing it. Or move to a (value)serialization that does not care about namespaces. E.g. JSON.