Originally Posted by
Shaggy Hiker
You're a whole lot closer than you give yourself credit for. There are some limitations to XML serialization, and this may be one of them, but check that first. An XML serialized file would work a bit more easily than a binary serialized file for what you are trying to do. The nice thing about an XML serialized file is that you can look to see whether it worked, and how it worked, and do so easily enough. Use either Wordpad or Notepad (one works well for this type of file, the other really does not, but I forget which it is) to open the file. XML has plenty of oddities in it, but even if you are not familiar with XML, it should look VERY familiar. In fact, it should show all of your data. However, it may not, because I seem to remember reading that XML serialization didn't work on arrays. I haven't used it, so I have no experience with it, but by opening the file you will probably be able to see whether or not all your data is there. Of course, if it IS all there, it would be very tedious to read, so you won't want to check everything. Basically, I would expect that either you would have barely anything, only one tile, or all of them. If you have all of them, then the problem lies with reading them back in. If you have one of the first two options, then XML serialization failed. You could start a different thread on that if you still wanted to pursue it. You are very close, as it stands, the only real question I have is whether or not XML serialization even works on arrays.
In any case, if you look at the binary serialization and compare it to what you already have, you will see that the two are quite similar. I wrapped things in an exception handler because you can never really trust files, but aside from that, the lines are really quite similar. You have an XMLSerializer, I have a BinaryFormatter. I used a memorystream, you used a file stream, but a stream is a stream, and a filestream is the one you want to be using. I then added in a bit about taking the stream and converting the bytes to a string, but that was just so I could put the data into a My.Settings property. Since you aren't doing that, you don't need any such thing.
Unfortunately, that does leave a couple complications. The first one is utterly trivial, as you need to decorate all structures that you want to serialize with the <Serializable()> attribute. You'd just put that before Public. You can do some goofy stuff with that, but you don't need to. I'm not quite sure what that attribute does, but I suspect it may have to do with how the structure is arranged in memory. In any case, you can't serialize anything that lacks the attribute.
The other complication is as I noted: Binary serialization includes the application that serialized it, and you can't deserialize it with a different application. XMLSerialization, and that binary file thing from VB6 rather finessed the problem because there isn't any type information included in any of that. XMLSerialization is just plain text with a minimal amount of structuring, whereas the VB6 routine was just writing some bytes. An integer probably took four bytes in such a file, and there was no problem with your reading back those four, or reading back only two of them, or reading back the wrong four. If you didn't do the reading exactly the way the data was organized in the file, you'd get something back, but it would be junk. What this meant was that using either of those two types of files, your map editor and your main program didn't have to have the same types at all. Most likely, you would copy the types from one to the other, so they both would have the same, but there would be nothing enforcing that other than your own whim (XML serialization would enforce it to some extent, but only very lightly, and you could circumvent that easily). In the map editor, you could name the structures something different, or the properties, or have fewer properties, or have them be different types (with some limitations). They would be the same only by chance.
Binary serialization doesn't allow that. If you serialize an array of MapRec, then any program that deserializes it has to have access to the MapRec type. It's not enough to just have a type called MapRec in the application, nor is it enough to have the right properties in that type. Instead, the program that deserializes the object must have the same object that was serialized, and therefore it must be the same Assembly. That means that you can't have one program serialize and a different program be able to do anything with that file. I haven't found a way around this, but then again, I haven't really bothered trying. In one case, I was serializing structures and sending them to various programs on various computers using UDP. The solution is really simple, but does take some organization. What I did was to create a dll (which is laughably simple in .NET), put the Serialize and Deserialize methods into that dll as public functions in a module, then I also added the types that would be shared between the programs (all the message structures, but you could do the same with the structures in your map). This isn't just necessary for the binary serialization, you would find it to be kind of convenient for what you are doing even if you weren't doing any serialization. After all, by creating such a dll and referencing the dll from both the program and the map editor, you have the same objects available in each. Otherwise, if you change the design of the object in one, you had better remember to change it in the other. By putting the common structures and classes into a dll, a change to the dll is seen by both projects. And then the problem with binary serialization goes away and the actual code is virtually what you already wrote for XMLSerialization except that it uses a binaryformatter instead of an XMLSerializer.
Of course, it also means that nobody can really write such a thing for you, though they might give you an example, but you barely need an example as you are so close already. Since the dll would be yours, you'd need to write it. If you haven't created one before, it might seem daunting, but you're already way beyond that point, since a dll would just be a new project of type Class Library, but is otherwise just like the other projects you've created.