I'm trying to serialize an object cache to disk so it can be loaded the next time the program is loaded.
One of the features of the class being saved is it contains references to other objects.
For example:
I have a list of an image class that stores remote url, local filepath, if it's been downloaded etc.... I then bind visibility to downloaded and the source to the local filepath.
Other Objects have a reference to this image so when the image is downloaded it's updated once and all the bindings update across all items that are pointing at it.
As a quick fix I implemented a binary formatter and all is working correctly. All my lists are serialized to disk and when I reload them all the references remain (I.E 1 image object is created and everything that uses it has a reference as opposed to deserialisation creating a new instance of Image everytime it appears)
My question is what kind of Serialier I should be using to store to disk whilst not breaking my references? I've read that BinaryFormatter is a BAD choice for serializing to disk and expecting it to work across different releases. Although I've had no issues with it so far I don't want to run into problems a year down the road and force all my users so re-aquire all their cached metadata.
I'm not 100% sure how all the different serializers work but I presume I may need to write some kind of convertor if I were to use XML. If it helps, all of my image objects have a GUID assigned to them so I have something unique about every object.
UPDATE: I've just found the following question which looks similar Maintain object references through Serialize/Deserialize
Can anyone tell me if Datacontractserializer is a good choice for long term serialization storage across different versions of an applciation Vs the downsides of binaryformatter?
No need for any converters and stuff, just check this out:
http://www.switchonthecode.com/tutorials/csharp-tutorial-xml-serialization
SqLite may help in it, its easy to use.
MongoDb may be useful. See MongoDB for C#
or other type of DataBase: DB4Object
and seems be SQLite useful. use blobs for store images as binary.
Related
I understand how serialization works and was wondering if there is a way to store an object on the disk and work with the object and save the changes.
I am trying to avoid directly doing this:
Opening the file
Deserializing the object
Changing the object
Serializing the changes by overwriting the old file
Is there a class that allows a file to be used as an object store, namely List<object> and working with it directly on the disk without having to complete the above processes?
Try DB4O. It seems to be a solution for your requirements.
I dont believe there is an out of the box solution for this. Just search on how to save arbitrary data in a file, and think up your own format.
You probably want to look at something like ESE which comes with Windows. There is a managed interface for it. Never used it though.
Either that or use a lightweight database e.g. SQLite, since effectively, if you want to add, remove and modify data on the disk, some kind of database is what you need.
Objectivity is another alternative. It supports computing across vast distributed networks or embedded in stand-alone devices that simply must not fail, enables persistent object management, virtually instantaneous traversal of complex, many-to-many relationships and graphs, and much more.
In Windows phone we can store and retrieve anything using
IsolatedStorageSettings.ApplicationSettings.Add("foo", bar);
IsolatedStorageSettings.ApplicationSettings["foo"]
Then why people are using "sharpSerializer" kind of things ?
The settings is a flat organization with key/value pairs. For simple objects that's not a problem but if you have rich collections and don't want the overhead of deserializing a list just to get to an element, the settings can be problematic. They also require the element to be serializable, whereas using the isolated storage file system you can control the serialization and serialize anything. Furthermore, you can choose the serialization strategy such as binary, JSON, XML, or otherwise. Finally, there is a limit to how effectively settings will serialize objects. I'm not sure what it is because it's not published but more than one developer has told me larger objects or large amounts of objects start to behave erratically, throwing exceptions or not persisting correctly, in the settings.
PS - also, since you mentioned Windows Phone 7, there are limits to settings whereas the file system does not have a quota.
The big problem with storing the objects in the ApplicationSettings is that the entire contents of the settings are serialized and deserialized together.
As soon as you access just one setting, all settings a deserialized and loaded in the Dictionary<string, object> that backs the ApplicationSettings. Hence its not good choice to store large number of settings or to store large objects that require significant serialization.
Off the top of my head:
IsolatedStorageSettings are typically slower to access and save to than IsolatedStorage files.
You can't save null in Settings, but you could create your own serialized representation of this.
The use of directories can make working with a large number of files much easier than requiring a long or complicated naming convention for the key to an object in Settings.
In some cases you may want to refer to an object stored in IsolatedStorage. You can't do this if it's saved in settings.
I suspect that objects added to Settings are still serialised in some way (in the background) - my guess would be binary serialization - as they need to be persisted to disk. By defining your own serializiaton you can be sure that this will work correctly/as expected. If you just rely on the system to do it you could end up with unexpected behaviour. If you have your own serialization you also have some guarantees on future and cross platform compatibility. (If that's a concern.)
Another important point that other didn't mention was that when you update your application by submitting a newer version to the marketplace, the entire ApplicationSettings get wiped off, as it is assumed that the new application will have its own defaults set. So it is always a good idea to serialize data in to the IsolatedStorage and not cram the AppSettings.
Where exactly does serialization comes into the picture? I read about serializtion on the 'net and I have come to know that
it is an interface that if implements in a class, means that it can be automatically be serialized and deserialized by the different serializers.
Give me a good reason why and when would a class needs to be serialized? Suppose once it's serialized, what happens exactly?
Serialization is needed whenever an object needs to be persisted or transmitted beyond the scope of its existence.
Persistence is the ability to save an object somewhere and load it later with the same state. For example:
You might need to store an object instance on disk as part of a file.
You might need to store an object in a database as a blob (binary large object).
Transmission is the ability to send an object outside of its original scope to some receiver. For example:
You might need to transmit an instance of an object to a remote machine.
You might need to transmit an instance to another AppDomain or process on the same machine.
For each of these, there must be some serial bit representation that can be stored, communicated, and then later used to reconstitute the original object. The process of turning an object into this series of bits is called "serialization", while the process of turning the series of bits into the original object is called "deserialization".
The actual representation of the object in serialized form can differ depending on what your goals are. For example, in C#, you have both XML serialization (via the XmlSerializer class) and binary serialization (through use of the BinaryFormatter class). Depending on your needs, you can even write your own custom serializer to do additional work such as compression or encryption. If you need a language- and platform-neutral serialization format, you can try Google's Protocol Buffers which now has support for .NET (I have not used this).
The XML representation mentioned above is good for storing an object in a standard format, but it can be verbose and slow depending on your needs. The binary representation saves on space but isn't as portable across languages and runtimes as XML is. The important point is that the serializer and deserializer must understand each other. This can be a problem when you start introducing backward and forward compatibility and versioning.
An example of potential serialization compatibility issues:
You release version 1.0 of your program which is able to serialize some Foo object to a file.
The user does some action to save his Foo to a file.
You release version 2.0 of your program with an updated Foo.
The user tries to open the version 1.0 file with your version 2.0 program.
This can be troublesome if the version 2.0 Foo has additional properties that the version 1.0 Foo didn't. You have to either explicitly not support this scenario or have some versioning story with your serialization. .NET can do some of this for you. In this case, you might also have the reverse problem: the user might try to open a version 2.0 Foo file with version 1.0 of your program.
I have not used these techniques myself, but .NET 2.0 and later has support for version tolerant serialization to support both forward and backward compatibility:
Tolerance of extraneous or unexpected data. This enables newer versions of the type to send data to older versions.
Tolerance of missing optional data. This enables older versions to send data to newer versions.
Serialization callbacks. This enables intelligent default value setting in cases where data is missing.
For example when you want to send objects over network or storing them into files.
Lets say you're creating a Savegame-format for a video-game. You then could make the class Player and every Enemy serializable. This way it would be easy to save the state of the current objects into a file.
On the other end, when writing a multiplayer-implementation for your game, you could send the Player serialized via network to the other clients, which then could handle these data.
In non-object-oriented languages, one would typically have data stored in memory in a pattern of bytes that would 'make sense' without reference to anything else. For example, a bunch of shapes in a graphics editor might simply have all their points stored consecutively. In such a program, simply storing the contents of all one's arrays to disk might yield a file which, when read back into those arrays would yield the original data.
In object-oriented languages, many objects are stored as references to other objects. Merely storing the contents of in-memory data structures will not be useful, because a reference to object #24601 won't say anything about what that object represents. While an object-oriented system may be able to do a pretty good job figuring out what the in-memory data "mean" and try to convert it automatically to a sensible format, it can't recognize all the distinctions between object references which point to the same object, and those that point to objects which happen to match. It's thus often necessary to help out the system when converting objects to a raw stream of bits.
Not classes, but the specific objects might be serialized to store in some persistent storage or to pass the object to another application/via network.
for example, when you want to send a object to some url, you might decide to send it in xml format. The process of converting from the in-memory object to (in this case) xml, is called serialization. Converting from xml to a in-memory is called de-serialization.
This is a general question concerning the Workflow Foundation (.NET 3.5) and versioning the data that it works with. We have a lot of custom activities that work with some data and this data may be interesting also for the future analysis of the already completed workflows (provided that we configure the tracking in such a way that it stores it in a serialized form).
It may be necessary to show the data from the past in the UI, but the data inevitably changes the structure (class definition / internal structure if it's dynamic) and the redeployed version of our library will contain the new data definition while the serialized data in the tracking database will be still in the old structure.
Is it better to use dynamic structures that don't change from the beginning (like a property bag) or rather later deal with the redeployment and somehow transform the serialized BLOB into the new one ? Have you ever used some approach in a similar scenario ?
A lot depends on how you deploy your application. If you use a strong name and deploy to the GAC or multiple private assembly paths deserializing a workflow will deserialize the exact version of your class. That means that you code must be able to work with multiple versions and that can be a bit of a pain. Storing data in a property bag is not going to help you there. If you use assembly redirects to point to the current version of an activity solves that part and I suppose using a property bag would make life simpler then. That said I tend to stick with dependency properties and regular serializable classes so far.
I did a series of blog posts about long running workflows and versioning where you run into exactly the same problem. Check here for more details.
Is it possible to store a .Net object in the registry?
I want to store a generic List<> in the registry, and then retrieve it and parse it back to the List.
Is this possible, or do I need to manually serialize it and then deserialize it back?
[UPDATE]
Following the posted answers, I am going to serialize the object and save it in the Current User's AppData folder.
It's possible, if the type included in the list is serializable. If that's the case, you can serialize it and store it in a string value.
But it's probably a very bad idea. The registry gets big enough as it is. Instead, put this kind of thing on the file system, in the All Users Application Data folder.
Why the registry?
The appropriate place to store these kind of serialised objects is usually in the users' Application Data folder or Isolated Storage. Though of course the method of serialisation is up to you. XML, binary etc, it's essentially a file on disk.
You could consider things like "Local Database" or SQL Server Express, depending on your data and concurrency needs.
Some applications do store a Most Recently Used (MRU) list in the registry, but that's just by iterating all the values of a given key. I don't recommend that approach.
Yeah, I think you'd have to serialize and deserialize it yourself. But you could store it either as a binary block or text/xml. It's possible that there is a size limit to registry data...
The big question is "is this a good thing to do?"
You will have to serialize it yourself. Beware that there might be limitations on the amount of data you can store, depending on the Windows version.
http://msdn.microsoft.com/en-us/library/ms724872(VS.85).aspx
I'll just say this first: this sounds like a really bad idea.
If you insist on doing this, you're going to have to serialize it first. The registry doesn't support inserting .NET objects.
You would have to serialize it. The registry only stores primitive values.
You would need to manually serialize it.
Not quite sure why you'd want to store .NET objects in the registry, as there's already existing functionality in the BCL that allows you to do this with XML configuration files... but saying that, it is of course possible to store .NET objects in the registry. You'd probably only want to do it if the size of the object was relatively small, but it shouldn't be a problem anyway. I guess that the obvious way to do it would be to use XML Serialization (without formatting/whitespace) and store the object as a serialized string value.