none
Retrieving object using C sharp RRS feed

  • Question

  •  How to retrieve a particular record(eg: 3rd record) from a file
     which is written using object serialization in C sharp, if each record is a
     object of same class?


    Tuesday, August 16, 2011 1:53 PM

Answers

  • I assume you use binary serialization. You need to deserialize until you reach the nth object you want. Small sample.

    I have a class like this that I serialize to a memorystream.

    	[Serializable]
    	public class DemoClass
    	{
    		public string Value
    		{
    			get;
    			set;
    		}
     
    		public DemoClass(string value)
    		{
    			this.Value = value;
    		}
    	}

    This is the code to serialize and read back 3 times to get the third object in stream.

    		MemoryStream ms = new MemoryStream();
     
    		BinaryFormatter formatter = new BinaryFormatter();
     
    		DemoClass dc1 = new DemoClass("one");
    		DemoClass dc2 = new DemoClass("two");
    		DemoClass dc3 = new DemoClass("three");
    		DemoClass dc4 = new DemoClass("four");
     
    		formatter.Serialize(ms, dc1);
    		formatter.Serialize(ms, dc2);
    		formatter.Serialize(ms, dc3);
    		formatter.Serialize(ms, dc4);
     
    		// Read third object
    		ms.Position = 0;
    			
    		DemoClass dcRead = null;
     
    		for (int n = 0; n < 3; n++)
    		{
    			dcRead = (DemoClass)formatter.Deserialize(ms);
    		}
     
    		Console.WriteLine(dcRead.Value);
    

     Since the strings are of different length I can not calculate the position of where an object is. You could write a index file while serializing if there are many objects but then why not move to a database like sql ce or sqlite.

    • Marked as answer by Paul Zhou Wednesday, August 24, 2011 6:42 AM
    Thursday, August 18, 2011 7:55 AM
    Moderator

All replies

  • You would need to have custom logic of identifying these records, based on which you can retrieve your particular record. Hope that answers your question. Otherwise please explain your question a little more.
    Wednesday, August 17, 2011 6:52 AM
  • I assume you use binary serialization. You need to deserialize until you reach the nth object you want. Small sample.

    I have a class like this that I serialize to a memorystream.

    	[Serializable]
    	public class DemoClass
    	{
    		public string Value
    		{
    			get;
    			set;
    		}
     
    		public DemoClass(string value)
    		{
    			this.Value = value;
    		}
    	}

    This is the code to serialize and read back 3 times to get the third object in stream.

    		MemoryStream ms = new MemoryStream();
     
    		BinaryFormatter formatter = new BinaryFormatter();
     
    		DemoClass dc1 = new DemoClass("one");
    		DemoClass dc2 = new DemoClass("two");
    		DemoClass dc3 = new DemoClass("three");
    		DemoClass dc4 = new DemoClass("four");
     
    		formatter.Serialize(ms, dc1);
    		formatter.Serialize(ms, dc2);
    		formatter.Serialize(ms, dc3);
    		formatter.Serialize(ms, dc4);
     
    		// Read third object
    		ms.Position = 0;
    			
    		DemoClass dcRead = null;
     
    		for (int n = 0; n < 3; n++)
    		{
    			dcRead = (DemoClass)formatter.Deserialize(ms);
    		}
     
    		Console.WriteLine(dcRead.Value);
    

     Since the strings are of different length I can not calculate the position of where an object is. You could write a index file while serializing if there are many objects but then why not move to a database like sql ce or sqlite.

    • Marked as answer by Paul Zhou Wednesday, August 24, 2011 6:42 AM
    Thursday, August 18, 2011 7:55 AM
    Moderator
  • Agree With Andreas.  Just a tip:  I am GUESSING you can find out the total bytes per object serialized, probably by examining the memory stream?  I would then write the file with a header listing the offsets of all objects.  These offsets can then be used when reading the file:  First read the header, then traverse the list of offsets and determine the offset of the nth required record.  Navigate to this offset and read, then deserialize.  This more complex method intends to avoid the need to traverse all previous-to-the-nth records.  Prefer this method if you have large number of records in the file in order to gain read performance.
    MCP
    Thursday, August 18, 2011 8:02 PM
  • Agree With Andreas.  Just a tip:  I am GUESSING you can find out the total bytes per object serialized, probably by examining the memory stream?  I would then write the file with a header listing the offsets of all objects.  These offsets can then be used when reading the file:  First read the header, then traverse the list of offsets and determine the offset of the nth required record.  Navigate to this offset and read, then deserialize.  This more complex method intends to avoid the need to traverse all previous-to-the-nth records.  Prefer this method if you have large number of records in the file in order to gain read performance.
    MCP


    Yes, so far as I am aware the binary data in a serialized stream does not contain the length of the stream, it should but MS have not done so.

    Part of the "reason" for this is that the serialization algorithm does not know the length until the serialization is completed, so I guess the algorithm just appends chunks of data until it done.

     

    Cap'n

     


    Thursday, August 18, 2011 9:42 PM
  • It would be bad if you could not obtain the number of bytes written to the stream indeed, but that doesn't appear to be the case by quickly browsing http://msdn.microsoft.com/en-us/library/system.io.memorystream.aspx.  It seems that MemoryStream.Length returns the total number of bytes written to the stream.  If you start with an empty stream, you can just keep on saving this Length value after each serialization and that would be the offset value of the next item.
    MCP
    Friday, August 19, 2011 1:00 AM
  • I am surprised to know that c# does not implement any object size determination funcions like sizeof(object) as we have in c++. 

     

    Sunday, August 28, 2011 5:14 AM