Search code examples
c#serializationdeserializationbinary-serialization

C# Manually Deserialization


I want to know if that's possible to manually parse a serialized binary which has been serialized in c#.

My end goal is to parse a serialized binary of a multi-dimensional array which has been serialized in c# and parse it in java,

I want to know if there is any algorithm/cheat-sheet that help me to understand the structure of a serialized binary?

Any pointers/hints greatly appreciated.

NOTE: I am not looking to deserialize the serialized object in Java, I want to know the structure of a binary serialized object, so i can parse it in a way that i want.


Solution

  • As suggested, XML can be great tool for this, here is a small demo example:

    C# serialization:

    // NEEDED IMPORTS
    using System.Collections.Generic;
    using System.IO;
    using System.Xml.Serialization;
    
    static void Main(string[] args)
    {
      // build a list of lists from 0 to 99 divided on 
      // 10 inner list each with 10 elements
      List<List<string>> list = new List<List<string>>();
      for(int i=0; i<10; i++)
      {
        list.Add(new List<string>());
        for (int j = i * 10; j < i * 10 + 10; j++)
          list[i].Add(j.ToString());
      }
    
      // serialize to xml 
      XmlSerializer ser = new XmlSerializer(list.GetType());
      TextWriter writer = new StreamWriter("serialized.xml");
      ser.Serialize(writer, list);
    }
    

    Sample output:

    <?xml version="1.0" encoding="utf-8"?>
    <ArrayOfArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <ArrayOfString>
        <string>0</string>
        <string>1</string>
        <string>2</string>
        <string>3</string>
        <string>4</string>
        <string>5</string>
        <string>6</string>
        <string>7</string>
        <string>8</string>
        <string>9</string>
      </ArrayOfString>
      
      ...
    

    Based on the serialized XML, Java deserialization:

    // NEEDED IMPORTS
    import java.io.*;
    import java.util.*;
    import org.jdom2.*;
    import org.jdom2.input.*;
    
    public static void main(String[] args) throws JDOMException, IOException {
        // build DOM from the XML file - generic for all XML files
        File fXmlFile = new File("serialized.xml"); // file we created in C#
        SAXBuilder builder = new SAXBuilder();
        Document document = builder.build(fXmlFile);
        Element root = document.getRootElement();
        
        // build List<List<String>> using expected format
        if(!root.getName().equals("ArrayOfArrayOfString")){
            System.out.println("invalid root element");
            return; 
        }
        
        List<List<String>> list = new ArrayList<>();
        
        List<Element> children = root.getChildren();
        for(int i = 0; i<children.size(); i++){
            Element child = children.get(i);
            if(child.getName().equals("ArrayOfString")){
                List<String> innerList = new ArrayList<>();
                list.add(innerList);
                List<Element> innerChildren = child.getChildren();
                for(int j=0; j < innerChildren.size(); j++){
                    Element elem = innerChildren.get(j);
                    if(elem.getName().equals("string"))
                        innerList.add(elem.getValue());
                }
            }
        }
        
        for(int i = 0; i<list.size(); i++){
            System.out.print(String.format("InnerList[%d]: ", i));
            List<String> innerList = list.get(i);
            for(int j=0; j<innerList.size(); j++)
                System.out.print(String.format("\"%s\" ",innerList.get(j)));
            System.out.println();
        }
    }
    

    Output:

    InnerList[0]: "0" "1" "2" "3" "4" "5" "6" "7" "8" "9"

    InnerList[1]: "10" "11" "12" "13" "14" "15" "16" "17" "18" "19"

    InnerList[2]: "20" "21" "22" "23" "24" "25" "26" "27" "28" "29"

    InnerList[3]: "30" "31" "32" "33" "34" "35" "36" "37" "38" "39"

    InnerList[4]: "40" "41" "42" "43" "44" "45" "46" "47" "48" "49"

    InnerList[5]: "50" "51" "52" "53" "54" "55" "56" "57" "58" "59"

    InnerList[6]: "60" "61" "62" "63" "64" "65" "66" "67" "68" "69"

    InnerList[7]: "70" "71" "72" "73" "74" "75" "76" "77" "78" "79"

    InnerList[8]: "80" "81" "82" "83" "84" "85" "86" "87" "88" "89"

    InnerList[9]: "90" "91" "92" "93" "94" "95" "96" "97" "98" "99"

    This is a very simple demonstration of what can be done using XML. I am not doing error handling in this code.


    Edit: The Java DOM builder is not directly from the JDK. You need to download it from their website: http://www.jdom.org/downloads/ and import the jre file to your Java project. I have also included the import statements needed for this operation.