输入流不是有效的二进制格式。起始内容 [英] The input stream is not a valid binary format. The starting contents

查看:131
本文介绍了输入流不是有效的二进制格式。起始内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我以前曾问过这类问题,但不确定问题的根本原因是什么或如何解决。

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.

我正在修改现有的类,以便能够将数据从flash加载到成员变量中。现在,该类通过加载功能从文件加载数据。此函数已重载以获取字节数组。

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.

从闪存读取的数据放入此字节数组中。

引发的错误是(发生在<$ c行$ c> ... = formatter.Deserialize(stream)):

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)):


输入流不是有效的二进制格式。起始内容(以字节为单位)为:93-E3-E6-3F-C3-F5-E4-41-00-C0-8D-C3-14-EE-4A-C3-00 ...

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.

或者更好的问题是 BinaryFormatter ?需要一定的尺寸吗?是否需要特定的最终价值?某些值无效吗?字节数组输入的当前大小为24个字节。

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.

代码:

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)
{
    try
    {

        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");
            }
            else
            {
                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");
        }
        else
        {
            property.SetValue(this, value, null);
        }
    }
}

请注意,我也尝试过将字节数组转换为对象函数(我在stackoverflow上找到)。当我使用此函数时, .Deserialize(memStream)仍会引发异常。

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.

串行化发生在与反序列化不同的应用程序中。序列化使用位转换器获取数据,转换为字节数组并将其上传到闪存。让我解释。正在序列化/反序列化的数据闪存中存储的是校准数据。校准是在工厂使用Application1按生产进行的。这使用位转换器将每个字段放入流中,然后序列化该流。

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);

其中函数FloatToStream定义为:

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.

另一方面,一旦产品出厂并在使用中,Application2(用户应用程序)将具有包含所有校准字段的Calibration对象。这将读取闪存,并获取由Application1写入的数据。 Application2尝试使用BinaryFormatter和上面的代码反序列化校准数据。我得出的结论是不可能的(谢谢Rotem)。正确的做法是对序列化/反序列化使用相同的格式化程序-我将以这种方式实现并指出是否有区别。

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.

推荐答案

更新之后,明显的问题是您正在使用不同的格式化程序进行序列化和反序列化。

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

BinaryFormatter 不仅对字段数据进行序列化。它还对类型信息和元数据进行序列化,因此它知道如何反序列化对象,因此它期望的不仅仅是输入原始数据字节。

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.

都可以使用 BinaryFormatter 在序列化端也是如此,或者在接收端使用手动反序列化技术。

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

这篇关于输入流不是有效的二进制格式。起始内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆