标签: binaryformatter

.NET中的序列化和混淆

我有一个二进制文件,我想混淆和分发给用户.让我们假设我使用我的二进制文件的未经模糊处理的版本来使用现成的.NET二进制格式化程序来序列化数据.那么我们可以用混淆的二进制文件对数据进行语义化吗?

我想发布混淆的二进制文件和序列化数据.如果上述问题的答案是肯定的,我可以在用户之间共享序列化数据.否则,我将不得不向每个用户提供单独的序列化数据.

.net obfuscation serialization binaryformatter

10
推荐指数
2
解决办法
2633
查看次数

性能:BinaryFormatter与XmlSerializer

我经常读到BinaryFormatter比XmlSerializer具有更好的性能.出于好奇,我写了一个测试应用程序.

一个wtf时刻......为什么Xml比Bin快得多(特别是反序列化)?

using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Xml.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;

namespace SerPlayground
{
    class Program
    {
        static void Main(string[] args)
        {
            var items = new List<TestClass>();
            for (int i = 0; i < 1E6; i++)
            {
                items.Add(new TestClass() { Name = i.ToString(), Id = i });
            }

            File.Delete("test.bin");
            using (var target = new FileStream("test.bin", FileMode.OpenOrCreate))
            {
                System.Threading.Thread.Sleep(1000);
                var bin = new BinaryFormatter();
                var start = DateTime.Now;
                bin.Serialize(target, items);
                Console.WriteLine("Bin: {0}", (DateTime.Now - start).TotalMilliseconds);

                target.Position = 0; …
Run Code Online (Sandbox Code Playgroud)

c# performance binaryformatter xmlserializer

9
推荐指数
1
解决办法
1万
查看次数

.NET与BinaryFormatter的向后兼容性

我们在C#游戏中使用BinaryFormatter来保存用户游戏进度,游戏关卡等.我们遇到了向后兼容性的问题.

目的:

  • 关卡设计师会创建广告系列(级别和规则),我们会更改代码,广告系列应该仍能正常运行.这可以在发布之前的每个开发期间发生.
  • 用户保存游戏,我们发布游戏补丁,用户应该仍然可以加载游戏
  • 无论两个版本有多远,无形数据转换过程都应该有效.例如,用户可以跳过我们的前5个小更新并直接获得第6个.尽管如此,他保存的游戏仍然可以正常运行.

解决方案需要对用户和关卡设计人员完全不可见,并且最低限度地要求更改某些内容的编码人员(例如,因为他们想要更好的名称而重命名字段).

我们序列化的一些对象图根植于一个类,一些在其他类中.不需要向前兼容性.

可能会发生变化(当我们序列化旧版本并反序列化为新版本时会发生什么):

  • 添加字段(获取默认初始化)
  • 更改字段类型(失败)
  • 重命名字段(相当于删除它并添加一个新字段)
  • 将属性更改为字段和返回(相当于重命名)
  • 更改自动实现的属性以使用支持字段(相当于重命名)
  • 添加超类(相当于将其字段添加到当前类)
  • 以不同的方式解释一个字段(例如,以度为单位,现在以弧度表示)
  • 对于实现ISerializable的类型,我们可以改变ISerializable方法的实现(例如,对于某些非常大的类型,在ISerializable实现中开始使用压缩)
  • 重命名一个类,重命名一个枚举值

我读过:

我目前的解决方案:

  • 我们通过使用像OnDeserializing回调之类的东西,尽可能多地进行更改.
  • 我们每两周安排一次重大更改,因此保留的兼容性代码较少.
  • 每次我们进行重大更改之前,我们会将我们使用的所有 [Serializable]类复制到名为OldClassVersions.VersionX的名称空间/文件夹中(其中X是最后一个之后的下一个序号).即使我们不打算很快发布,我们也会这样做.
  • 在写入文件时,我们序列化的是这个类的一个实例:class SaveFileData {int version; 对象数据; }
  • 从文件中读取时,我们反序列化SaveFileData并将其传递给迭代的"更新"例程,该例程执行如下操作:

.

for(int i = loadedData.version; i < CurrentVersion; i++)
{
    // Update() takes an instance of OldVersions.VersionX.TheClass
    // and returns an instance of OldVersions.VersionXPlus1.TheClass
    loadedData.data = Update(loadedData.data, i);
}
Run Code Online (Sandbox Code Playgroud)
  • 为方便起见,Update()函数在其实现中可以使用CopyOverlappingPart()函数,该函数使用反射将尽可能多的数据从旧版本复制到新版本.这样,Update()函数只能处理实际更改的内容.

有些问题:

  • 反序列化器反序列化为类Foo而不是类OldClassVersions.Version5.Foo - 因为类Foo是序列化的.
  • 几乎不可能测试或调试
  • 需要保留很多类的旧副本,这容易出错,易碎且烦人
  • 当我们想要重命名一个类时,我不知道该怎么做

这应该是一个非常普遍的问题.人们通常如何解决它?

.net backwards-compatibility binaryformatter

9
推荐指数
1
解决办法
3821
查看次数

不总是调用OnSerializing/OnSerialized方法

这是我在项目中序列化的结构:

[Serializable]
class A : List<B> //root object being serialized

[Serializable]
class B
  + [A few serializable fields]
  + C customList

[Serializable]
class C : List<D>

[Serializable]
class D
  + [several serializable fields]
  |
  + [NonSerialized] nonserializable3rdPartyClass data
  + string xmlOf3rdPartyData
  |
  + [OnSerializing]
  + private void OnSerializing(StreamingContext context)
  |
  + [OnSerialized]
  + private void OnSerialized(StreamingContext context)
  |
  + [OnDeserialized]
  + private void OnDeserialized(StreamingContext context)
Run Code Online (Sandbox Code Playgroud)

nonserializable3rdPartyClass,虽然没有标记为[Serializable]提供.ToXml.FromXml我在我的使用方法.OnSerializing.OnDeserialized方法,分别存储和检索XML字符串xmlof3rdPartyData. …

c# serialization binaryformatter

9
推荐指数
1
解决办法
4468
查看次数

BinaryFormatter异常

我正在尝试将对象图从服务器进程移动到客户端.它有效.至少它可以在客户端和服务器都在我的开发虚拟机上时工作.当我在我的基本机器(dev vm上的客户端)上运行服务器时,它也可以工作.

当我在媒体中心PC上运行服务器时,它停止工作.例外是:

二进制流'0'不包含有效的BinaryHeader.可能的原因是序列化和反序列化之间的无效流或对象版本更改.

这三台PC都是x64 Windows 7机器.我正在使用TCPClient和TCPListener以及BinaryFormatter类来完成繁重的工作.

使用标准FileStream对象从文件中读取正在传输的数据.

如果在客户端我将缓冲区序列化为文件,那么内容(根据BeyondCompare)确实看起来确实有所不同?!?

我的对象上的所有字符串属性都是在setter中进行Base64编码并在getter中解码.

我可以发布代码,但我不确定问题所在的位置?有任何想法吗?

.net c# serialization exception binaryformatter

8
推荐指数
1
解决办法
1687
查看次数

.NET中的程序集独立序列化

我使用序列化/去序列化技术.BinaryFormatter类.每次创建新程序集时,即使类结构相同,BinaryFormatter也不能反序列化二进制数据,但程序集版本不同.如果类结构保持不变,是否可以反序列化二进制缓冲区而不检查程序集版本?

c# binaryformatter deserialization

8
推荐指数
2
解决办法
4604
查看次数

BinaryFormatter中的引用完整性

Protobuf-net中存在AsReference选项,而BinaryFormatter是一个"图形序列化器",这使我认为BinaryFormatter不维护引用,并且它会复制每个对象.

但我做了一些测试,发现即使对于递归引用,单个BinaryFormatter Serialize()或Deserialize()调用中的所有引用都会被维护.

我可以确认BinaryFormatter确实维护引用吗?这与Protobuf-net有何不同?好像我理解"图形序列化"不正确?我还应该注意什么?

提前致谢.

c# reference protobuf-net binaryformatter

8
推荐指数
1
解决办法
1225
查看次数

StreamingContextStates.Clone实际上做了什么?

本书CLR Via C#介绍了一种通过二进制序列化克隆对象的简单方法.

它指定StreamingContextStates.Clone何时创建BinaryFormatter类似:

var formatter = new BinaryFormatter
{
    Context = new StreamingContext(StreamingContextStates.Clone)
};
Run Code Online (Sandbox Code Playgroud)

文档StreamingContextStates.Clone说它

指定正在克隆对象图.用户可以假设克隆的图形将继续存在于同一进程中,并且可以安全地访问句柄或对非托管资源的其他引用.

很公平 - 但我真的不知道这实际意味着什么.这实际上以什么方式改变了行为BinaryFormatter?任何人都可以列出使用此标志的具体效果吗?

c# serialization binaryformatter

8
推荐指数
1
解决办法
301
查看次数

将巨大的longs数组写入磁盘

我需要将大量的long(最多5GB)数组写入磁盘.我尝试使用,BinaryFormatter但它似乎只能编写大小低于2GB的数组:

long[] array = data.ToArray();
FileStream fs = new FileStream(dst, FileMode.Create);
BinaryFormatter formatter = new BinaryFormatter();
try
{
    formatter.Serialize(fs, array);
}
catch (SerializationException e)
{
    Console.WriteLine("Failed to serialize. Reason: " + e.Message);
    throw;
}
finally
{
    fs.Close();
}
Run Code Online (Sandbox Code Playgroud)

此代码抛出IndexOutOfRangeException较大的数组.

我不想为每个元素保存元素,因为它需要太多时间.有没有正确的方法来保存这么大的阵列?

每个元素编写元素:

using (BinaryWriter writer = new BinaryWriter(File.Open(dst, FileMode.Create)))
{
    foreach(long v in array)
    {
        writer.Write(v);
    }
} 
Run Code Online (Sandbox Code Playgroud)

这很慢.

c# arrays binaryformatter

8
推荐指数
1
解决办法
1198
查看次数

二进制序列化本质上是不安全的吗?

微软警告不要使用BinaryFormatter(他们写道没有办法保证反序列化的安全)。

应用程序应尽快停止使用 BinaryFormatter,即使它们认为正在处理的数据是值得信赖的。

我不想使用基于XMLJson的解决方案(这是他们所指的)。我担心文件大小和保留对象图。

如果我要编写自己的方法来遍历我的对象图并将对象转换为二进制,那么可以安全地制作它,还是从二进制转换为特殊内容使其本质上比文本更危险?

c# binaryformatter

7
推荐指数
1
解决办法
5791
查看次数