views:

2441

answers:

8

Hello,

I am heavily using byte array to transfer objects, primitive data, over the network and back. I adapt java's approach, by having a type implement ISerializable, which contains two methods, as part of the interface, ReadObjectData and WriteObjectData. Any class using this interface, would write date into the byte array. Something Like that

  class SerializationType:ISerializable
    {
       void ReadObjectData (/*Type that manages the write/reads into the byte array*/){}
       void WriteObjectData(/*Type that manages the write/reads into the byte array*/){}  
    }

After write is complete for all object, I send an array of the network.


This is actually two-fold question. Is it a right way to send data over the network for the most efficiency (in terms of speed, size)?

Would you use this approach to write objects into the file, as opposed to use typically xml serialization?

Edit #1

Joel Coehoorn mentioned BinaryFormatter. I have never used this class. Would you elaborate, provide good example, references, recommendations, current practices -- in addition to what I currently see on msdn?

A: 

You may want to read this thread.

dirkgently
Thanks, it has some good info but mostly not relevant to the question.
A: 

Creating your own ISerializable interface when there's already one in the framework sounds like a bit of a recipe for disaster. At least give it a different name.

You'll have a bit of a problem when it comes to reading - you won't have an instance to call the method on. You might want to make it a sort of "factory" instead:

public interface ISerializationFactory<T>
{
    T ReadObjectData(Stream input);
    void WriteObjectData(Stream output);
}

As for XML vs binary... it entirely depends on the situation: how much data will there be, do you need backwards and forwards compatibility, does the XML serialization in .NET give you enough control already etc.

Jon Skeet
When was ISerializationFactory introduced? ISerializable is an internal interface, so I can easily modify all serialization types.... I will take a note of it. Thanks
A: 

Yes this will be faster than sending XML as you will be sending less data over the wire. Even if you compressed the XML (which would drastically reduce its size) you would still have the overhead of compression and decompression. So I would say that between what you are currently doing and XML serialization you are currently using the most efficient solution.

However I am curious as to how much of a performance hit you would incur by using XML instead of a marshaled object. The reason that I would encourage you to look into XML serialization is because you will be storing the data in an application-neutral format that is also human readable. If you are able to serialize the data to XML in a way that does not incur performance penalties in your application I would recommend that you look into it.

Andrew Hare
Good Idea. I suppose for storing file, a xml file is a good idea. As for the wire transfer, specific to my case, i cannot use xml, as the other end receiving data is C++ server that only reads and writes data one way, and one way alone -- to/from byte array. Thanks
A: 

Regarding writing to file, generally you want to serialize an object to XML if you want to be able to read the serialization or perhaps alter it. If you have no desire for the serialization to be human readable, you might as well reuse your binary serialization.

If you do want it to be human readable, then XML is something to consider, but it depends on the type of data you need to serialize. XML is inherently recursive and is therefore good for serializing likewise recursive data. It's less of a good fit on other types of data.

In other words, pick a persistent serialization that suits your needs. There's no one-way-fits-all solution here.

As for network, generally you'll want to keep size to a minimum, so XML is usually never a good choice due to its verbosity.

Welbog
A: 

Serialization (in Java) is deceptively simple. As long as you do simple stuff (like never change the class) it is easy - but there are a number of "fun" things with it too.

Foe a good discussion on Java serialization look at Effective Java (specifically chapter 10).

For C#, not sure, but likely the core issues are the same.

There is an example here on C# serialization: http://www.codeproject.com/KB/cs/objserial.aspx.

TofuBeer
Effective Java is a great book -- I read both edition cover to cover!
+6  A: 

This should be fine, but you're doing work that is already done for you. Look at the System.Runtime.Serialization.Formatters.Binary.BinaryFormatter class.

Rather than needing to implement your own Read/WriteOjbectData() methods for each specific type you can just use this class that can already handle most any object. It basically takes an exact copy of the memory representation of almost any .Net object and writes it to or reads it from a stream:

BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(outputStream, objectToSerialize);

objectToDeserialize = bf.Deserialize(inputStream) as DeserializedType;

Make sure you read through the linked documents: there can be issues with unicode strings, and an exact memory representation isn't always appropriate (things like open Sockets, for example).

Joel Coehoorn
Nice... elaborate on this class please....
That may not work well if a specific layout in the binary array is required.
That's right: it does assume .Net at both ends, or that any non-.Net participant will parse the .Net format.
Joel Coehoorn
BinaryFormatter is implementation-specific, version-intolerant, and not especially quick for large graphs - but it is, of course, perfectly functional for .net-to-.net. Personally, I'd go for protobuf-net, of course ;-p
Marc Gravell
A: 

XStream library provide an exceptionally good way of dealing with serialisation including support for XML, JSON and supporting custom converters. Specifically, the use of custom converters allowed us to reduce XML verbosity and to serialise strictly what is needed.

XStream has no requirement to declare everything as Serializable, which is very important when one utilises a third-party lib and needs to serialise an instance of a class from that lib, which is not declared as Serializable.


The answer is already accepted, but for the sake of completeness of this discussion here is a link to a good comparison between different serialisation approaches/libraries:

http://code.google.com/p/thrift-protobuf-compare/wiki/Benchmarking

The kryo library looks very compelling for Java serialisation. Similarly to XStream is supports custom converters.

01es
looks good [for personal use]. I'm not sure I want to include it into commercial code, until at least I fully understand license guidelines.It only facilitates file serialization. I need something for network too. thanks
We're using it specifically for network communication (as a way to communicate between a REST service and a client). A two minute tutorial [http://xstream.codehaus.org/tutorial.html] shows that one can simply write String xml = xstream.toXML(joe); and then do with xml what ever is needed.
01es
+2  A: 

If you are after simple, lightweight and efficient binary serialization, consider protobuf-net; based on google's protocol buffers format, but implemented from scratch for typical .NET usage. In particular, it can be used either standalone (via protobuf-net's Serializer), or via BinaryFormatter by implementing ISerializable (and delegating to Serializer).

Apart from being efficient, this format is designed to be extensible and portable (i.e. compatible with java/php/C++ "protocol buffers" implementations), unlike BinaryFormatter that is both implementation-specific and version-intolerant. And it means you don't have to mess around writing any serialization code...

Marc Gravell