In C# how can I serialize a List<int> to a byte[] in order to store it in a DB field?

In C# how can I serialize a List<int> to a byte[] in order to store it in a DB field?

I know how to serialize to a file on the disk, but how do I just serialize to a variable?

Here is how I serialized to the disk:

            List<int> l = IenumerableofInts.ToList();
            Stream s = File.OpenWrite("file.bin");
            BinaryFormatter bf = new BinaryFormatter();
            bf.Serialize(s, lR);
            s.Close();

I'm sure it's much the same but I just can't wrap my head around it.

Answers


Use a MemoryStream instead of the file stream:

Stream s = new MemoryStream();

This will place the data in the s variable, which you can read later on in your application.

In order to read from it, you will need to set the Position to 0, so seeking will start from the beginning of the stream (if reading in chunks), or use ToArray() on it to retrieve the complete content.


To put it bluntly: I would put them in another table in the database that has a one-to-many foreign-key relationship with its parent record.

That way, you can do normal DB operations with them, like retrieving parent records based on which ints are in the child table.


Personally, I would not use BinaryFormatter for this purpose - it is implementation specific and overly expensive. I would be tempted to (one of):

1: use BinaryWriter / BinaryReader to do it manually (but note that this is easy to interpret from any API):

    // note I've used arrays in the example; lists are identical
    int[] data = { 1, 2, 3, 4, 5 };
    byte[] raw;
    using (var ms = new MemoryStream())
    using (var writer = new BinaryWriter(ms))
    {
        writer.Write(data.Length);
        foreach(int i in data) {
            writer.Write(i);
        }
        writer.Close();
        raw = ms.ToArray();
    }
    // read it back
    using (var ms = new MemoryStream(raw))
    using (var reader = new BinaryReader(ms))
    {
        int count = reader.ReadInt32();
        data = new int[count];
        for (int i = 0; i < count; i++)
        {
            data[i] = reader.ReadInt32();
        }
    }

or 2: use an implemenation-independent serialization format, such as protobuf; here I'm using protobuf-net

    int[] data = { 1, 2, 3, 4, 5 };
    byte[] raw;
    using (var ms = new MemoryStream()) {
        Serializer.Serialize(ms, data);
        raw = ms.ToArray();
    }
    // read it back
    using (var ms = new MemoryStream(raw)) {
        data = Serializer.Deserialize<int[]>(ms);
    }

Note that (1) uses 24 bytes for the example (6 * 4 bytes); (2) uses 10 bytes (in part because the numbers are simple, but actually protobuf has some tricks (such as "packed" data) that we aren't even using here).


Use a generic serializer

private static string SerializeObject<T>(T source)
{
    var serializer = new XmlSerializer(typeof(T));

    using (var sw = new System.IO.StringWriter())
    using (var writer = new XmlTextWriter(sw))
    {
        serializer.Serialize(writer, source);
        return sw.ToString();
    }
}

http://weblogs.asp.net/rajbk/archive/2009/10/04/xmlserializer-and-invalid-xml.aspx


Need Your Help

Angular controller in ui router scope does not change when working with ui modal

javascript angularjs angularjs-directive angularjs-scope angular-ui-router

I am confused with the scope in ui modal controller when using 'controller as in the ui router. I tried to keep using the same controller (CompanyCtrl) as the controller for modal so that I can add...