【问题标题】:cast a stream or byte array to object将流或字节数组强制转换为对象
【发布时间】:2015-02-09 18:30:07
【问题描述】:

在我们的游戏中,为了保存一个“Ghost”(一个可序列化的类,记录某人如何玩关卡),我们使用简单

BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Open(filePath, FileMode.Open);
object ghost = bf.Deserialize(file);
file.Close();
return (Ghost)ghost;

完美的工作,并拯救一个幽灵,

BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Create(filePath);
bf.Serialize(file, ghost);
file.Close();

再次,完美。

问题是,我们也在从 Web 加载内容(特别是 Amazon S3),最终提供了一个通用流。

我想要做的是将该流保存到文件中,

using( BinaryReader reader = new BinaryReader(stream) )
{
    FileStream file = File.Create(downloadPath);
    byte[] array = ReadAllBytes(reader);
    file.Write(array, 0, array.Length);
    file.Close();
}

但也将这些字节传递回请求代码,以便能够将它们转换为 Ghost 对象。目前,我们保存了 ghost,告诉请求的代码它已保存,然后他们再次从那里读取它,这是可行的,但我 99% 确信当我们已经有了可用的字节时,这是一个不必要的步骤。

有点c#菜鸟,我见过的关于反序列化的每个例子都涉及File对象。任何指针显然将不胜感激。

【问题讨论】:

  • 如果您已经获得了序列化的字节数组,那么只需从中创建一个 MemoryStream 并使用 BinaryFormatter 从那里反序列化。
  • 我实际上不需要。已经存在的stream 已经兼容,BinaryFormatter 可以接受,正如@CCondron 在下面回答的那样。

标签: c# unity3d stream bytearray deserialization


【解决方案1】:

内存流的语义与文件流的工作方式相同。您拥有的示例应该以与替换文件流的内存流相同的方式工作。 您也可以在不安全的代码中执行此操作,但这对于您在此处尝试执行的操作似乎有些过分。 像这样的东西应该可以工作:

 var bf = new BinaryFormatter();
 object ghost = bf.Deserialize(stream);
 return ghost;

阅读器应该是不需要的,但我不知道你得到什么样的流。

当然,一旦你在内存中拥有了 ghost 对象,就可以将副本序列化到磁盘。

【讨论】:

  • 不敢相信我错过了。我一直在 BinaryFormatter API 页面和所有内容上,但完全错过了反序列化的流选项。这是从 Eclipse 的转变,我认为这对我影响更大,我会检查它的每一个代码提示,如果我一直在使用它,我会在类定义中四处寻找。嗯,总有一天我会在 MonoDevelop 中感到自在!谢谢@CCondron。
【解决方案2】:

请注意,根据官方 .NET 文档:BinaryFormatter security guide,应避免使用 BinaryFormatter

一些推荐的替代方案是:

  • XmlSerializerDataContractSerializer 用于在 XML 中序列化/反序列化对象;
  • BinaryReaderBinaryWriter 用于 XML 和 JSON 数据格式;
  • System.Text.Json 用于将对象序列化/反序列化到内存和从内存到 JSON 的 API。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-19
    • 1970-01-01
    • 2014-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-30
    • 2015-08-05
    相关资源
    最近更新 更多