添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I've seen this type of question asked before but not sure what the root cause of the problem was or how to fix it.

I am modifying an existing class to be able to load data into the member variables from flash. Right now, the class loads data from a file through the load function. This function has been overloaded to take in byte array.

The data read back from the flash is put into this byte array.
The error that is thrown is (happens at the line ... = formatter.Deserialize(stream) ):

The input stream is not a valid binary format. The starting contents (in bytes) are: 93-E3-E6-3F-C3-F5-E4-41-00-C0-8D-C3-14-EE-4A-C3-00 ...

The interesting thing here is that the contents are exactly the contents of the byte array that is being passed into the stream. In other words, this is the data from the flash and this is exactly what I want serialized. I'm not sure why the error is being thrown.

Or a better question is what is a is a valid binary format for a BinaryFormatter ? Does it need a certain size? Is there specific end value needed? Are certain values invalid? The current size of the byte array input is 24 bytes.

Code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Windows.Media.Imaging;
using System.IO;
using Galileo.Data;
using System.Xml.Serialization;
using System.Reflection;
using System.Runtime.InteropServices;
using UComm;
using System.Runtime.Serialization.Formatters.Binary;
using ULog;
public void Load(byte[] spCalfromPrimary)
        Type settingsType = this.GetType();
        object tmp = Activator.CreateInstance(settingsType);
        Stream stream = new MemoryStream();
        stream.Write(spCalfromPrimary, 0, spCalfromPrimary.Length);
        stream.Position = 0;
        BinaryFormatter formatter = new BinaryFormatter();
        //tmp = formatter.Deserialize(stream);
        formatter.Deserialize(stream);            //**<--- throws error here**
        // Use reflection to copy all public properties from the temporary object into this one.                
        PropertyInfo[] properties = settingsType.GetProperties();
        foreach (PropertyInfo property in properties)
            object value = property.GetValue(tmp, null);
            if (value == null)
                throw new FileFormatException("Null value encountered in settings file");
                property.SetValue(this, value, null);
    catch (Exception ex)
        _logger.DebugException("Failed to load spatial cal value from FW", ex);
        Console.WriteLine(ex.Message);
// <summary>
/// Loads the setting from file
/// </summary>
public void Load()
    Type settingsType = this.GetType();
    XmlSerializer xser = new XmlSerializer(settingsType);
    object tmp = Activator.CreateInstance(settingsType);
    using (StreamReader reader = new StreamReader(_filename)) { tmp = xser.Deserialize(reader); }
    // Use reflection to copy all public properties from the temporary object into this one.                
    PropertyInfo[] properties = settingsType.GetProperties();
    foreach (PropertyInfo property in properties)
        object value = property.GetValue(tmp, null);
        if (value == null)
            throw new FileFormatException("Null value encountered in settings file");
            property.SetValue(this, value, null);

Note that I have also tried the a Convert byte array to object function (I found on stackoverflow). When I used this function, an exception was still thrown at .Deserialize(memStream).

// Convert a byte array to an Object
private Object ByteArrayToObject(byte[] arrBytes)
    MemoryStream memStream = new MemoryStream();
    BinaryFormatter binForm = new BinaryFormatter();
    memStream.Write(arrBytes, 0, arrBytes.Length);
    memStream.Seek(0, SeekOrigin.Begin);
    Object obj = (Object) binForm.Deserialize(memStream);
    return obj;

Apparently I left out some important information.

Serialization happens in a different application from deserialization. Serialization uses a bitconverter to take the data, convert to a byte array and upload it to flash. Let me explain. The data that is being serialized / deserialized & stored in flash is calibration data. Calibration is performed at the factory with Application1 by production. This uses a bitconverter to put every field into a stream and then serialize the stream.

CFlatInterface.FloatToStream(bData, ref i, rtsMappingData.ScaleTrackingDMD);
CFlatInterface.FloatToStream(bData, ref i, rtsMappingData.RotationAngle);
CFlatInterface.FloatToStream(bData, ref i, rtsMappingData.CenterOfRotation.dx);

where the function FloatToStream is defined as:

public static void FloatToStream(byte[] buf, ref int index, float val)
    Buffer.BlockCopy(BitConverter.GetBytes(val), 0, buf, index, sizeof(float));
    index += sizeof(float);

So every field that makes up the Calibration is put into the stream this way. The data is put into the stream and a byte array is constructed and sent to flash.

On the other side, once the product is out of the factory and in use, Application2 (user application) has a Calibration object that has all the calibration fields. This reads the flash, and gets the data that was written by Application1. Application2 is trying to deserialize the calibration data using BinaryFormatter and the code above. I am coming to the conclusion this is not possible (Thanks Rotem). The correct course of action is to use the same formatter for both serialization / deserialization - i will implement it this way and indicate if that makes a difference.

What is serializing the stream? BinaryFormatter can only deserialize data that were serialized with BinaryFormatter. – Rotem Feb 16, 2014 at 16:12

Following your update, the obvious issue is that you are serializing and deserializing with different formatters.

BinaryFormatter serializes more than just field data. It also serializes type information and metadata so it knows how to deserialize the objects, so it is expecting more than just raw data bytes as input.

Either use a BinaryFormatter on the serializing end as well, or use a manual deserialization technique on the receiving end.

I had the same problem and I solved it by serializing (Saving) with BinaryFormatter, and reading again with BinaryFormatter. – Santi Peñate-Vera Jun 11, 2014 at 7:38 how can we do "manual deserialization technique", I have to de-serialize into PSCustomObject – Ranvir Jul 29, 2014 at 7:49 @Ranvir That depends on how you are doing serialization. In the question, the OP was serializing using the raw bytes of certain values, which they got using BitConveter. – Rotem Jul 29, 2014 at 8:08 I am using BinaryFormatter in both serialization and deserialization and getting this error – John Demetriou Oct 26, 2016 at 7:05

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.