Binary stream does not contain a valid BinaryHeader

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • BH

    Binary stream does not contain a valid BinaryHeader

    I'm trying a simple object serialization and deserialization , and keep
    getting this error:

    System.Runtime. Serialization.S erializationExc eption: Binary stream does not
    contain a valid BinaryHeader, 0 possible causes, invalid stream or object
    version change between serialization and deserialization .

    Here's my code. it does nothing but to serialize a DataTable object into a
    byte array, and then read the byte array back for deserialization . I
    verified that the byte array length did not change. the error occurs on the
    object newObj = formatter.Deser ialize(ms2); line.

    public class Test {
    Public Test {

    DataTable dt = this.CreateData Source();
    System.IO.Strea m ms= new System.IO.Memor yStream();
    IFormatter formatter = new BinaryFormatter ();
    formatter.Seria lize(ms, dt);

    int numBytesToRead = (int) ms.Length;
    byte[] bytes = new byte[numBytesToRead];
    int numBytesRead = 0;
    int n = ms.Read(bytes, numBytesRead, numBytesToRead) ;
    ms.Position = 0;
    ms.Close();

    System.IO.Strea m ms2= new System.IO.Memor yStream();
    int numBytesToWrite = bytes.Length;
    ms2.SetLength(n umBytesToWrite) ;
    int numBytesWritten = 0;
    ms2.Write(bytes , numBytesWritten , numBytesToWrite );

    ms2.Position = 0;
    object newObj = formatter.Deser ialize(ms2);

    ms2.Close();
    }


    private DataTable CreateDataSourc e() {
    DataTable dt = new DataTable();
    DataRow dr;

    dt.Columns.Add( new DataColumn("Int egerValue", typeof(Int32))) ;
    dt.Columns.Add( new DataColumn("Str ingValue", typeof(string)) );
    dt.Columns.Add( new DataColumn("Cur rencyValue", typeof(double)) );

    for (int i = 0; i < 10; i++) {
    dr = dt.NewRow();

    dr[0] = i;
    dr[1] = "Item " + i.ToString();
    dr[2] = 1.23 * (i+1);

    dt.Rows.Add(dr) ;
    }
    return dt;
    }
    }



  • Jon Skeet

    #2
    Re: Binary stream does not contain a valid BinaryHeader

    BH <bobatkpmg@yaho o.com> wrote:[color=blue]
    > I'm trying a simple object serialization and deserialization , and keep
    > getting this error:
    >
    > System.Runtime. Serialization.S erializationExc eption: Binary stream does not
    > contain a valid BinaryHeader, 0 possible causes, invalid stream or object
    > version change between serialization and deserialization .
    >
    > Here's my code.[/color]

    That's not your code. When you're going to post code, *please* post the
    actual code - the code you posted doesn't compile. However, when
    (adding using statements, etc) I got your code to compile, the problem
    is pretty simple - and it's nothing to do with serialization, really.
    [color=blue]
    > public class Test {
    > Public Test {
    >
    > DataTable dt = this.CreateData Source();
    > System.IO.Strea m ms= new System.IO.Memor yStream();
    > IFormatter formatter = new BinaryFormatter ();
    > formatter.Seria lize(ms, dt);
    >
    > int numBytesToRead = (int) ms.Length;
    > byte[] bytes = new byte[numBytesToRead];
    > int numBytesRead = 0;
    > int n = ms.Read(bytes, numBytesRead, numBytesToRead) ;
    > ms.Position = 0;
    > ms.Close();[/color]

    All the mistakes are in this section.

    Firstly, you're trying to read *before* rewinding the stream - in other
    words, you write to the stream, but then try to read *from the end*.

    Secondly, when you read you're trying to read, you're trying to read at
    the end of the byte array rather than the start.

    Thirdly, you're assuming that everything will be read in one chunk
    (which it probably will with a MemoryStream, but don't make that
    assumption for streams in general). See
    http://www.yoda.arachsys.com/csharp/readbinary.html for more details.

    Fourthly, you're not flushing the stream after writing to it. Close()
    will do this for you, and in a MemoryStream it's probably not necessary
    anyway, but if you're going to do anything other than write then close,
    I'd recommend calling flush anyway.

    Now, taking the above points into consideration (except number 3 for
    the moment, because it wasn't harming your code in reality, would be a
    minor pain to demonstrate, is unnecessary for reasons explained in a
    moment, and probably wouldn't be what you'd use in real serialization)
    we end up with:

    DataTable dt = CreateDataSourc e();
    System.IO.Strea m ms= new System.IO.Memor yStream();
    IFormatter formatter = new BinaryFormatter ();
    formatter.Seria lize(ms, dt);
    ms.Flush();
    ms.Position = 0;

    int numBytesToRead = (int) ms.Length;
    byte[] bytes = new byte[numBytesToRead];
    ms.Read(bytes, 0, numBytesToRead) ;
    ms.Close();

    which works.

    However, simpler is:
    DataTable dt = CreateDataSourc e();
    System.IO.Strea m ms= new System.IO.Memor yStream();
    IFormatter formatter = new BinaryFormatter ();
    formatter.Seria lize(ms, dt);
    ms.Flush();
    byte[] bytes = ms.ToArray();
    ms.Close();

    Of course, simpler than that is just to rewind the memory stream and
    use the same stream for deserializing as we just serialized into:

    DataTable dt = CreateDataSourc e();
    System.IO.Strea m ms= new System.IO.Memor yStream();
    IFormatter formatter = new BinaryFormatter ();
    formatter.Seria lize(ms, dt);
    ms.Flush();
    ms.Position=0;
    object newObj = formatter.Deser ialize(ms);
    ms.Close();

    but maybe that doesn't show what you wanted to show.

    Anyway, hope this helped.

    --
    Jon Skeet - <skeet@pobox.co m>
    Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.

    If replying to the group, please do not mail me too

    Comment

    Working...