我有一个二进制文件,我想混淆和分发给用户.让我们假设我使用我的二进制文件的未经模糊处理的版本来使用现成的.NET二进制格式化程序来序列化数据.那么我们可以用混淆的二进制文件对数据进行语义化吗?
我想发布混淆的二进制文件和序列化数据.如果上述问题的答案是肯定的,我可以在用户之间共享序列化数据.否则,我将不得不向每个用户提供单独的序列化数据.
我经常读到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#游戏中使用BinaryFormatter来保存用户游戏进度,游戏关卡等.我们遇到了向后兼容性的问题.
目的:
解决方案需要对用户和关卡设计人员完全不可见,并且最低限度地要求更改某些内容的编码人员(例如,因为他们想要更好的名称而重命名字段).
我们序列化的一些对象图根植于一个类,一些在其他类中.不需要向前兼容性.
可能会发生变化(当我们序列化旧版本并反序列化为新版本时会发生什么):
我读过:
我目前的解决方案:
.
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)
有些问题:
这应该是一个非常普遍的问题.人们通常如何解决它?
这是我在项目中序列化的结构:
[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. …
我正在尝试将对象图从服务器进程移动到客户端.它有效.至少它可以在客户端和服务器都在我的开发虚拟机上时工作.当我在我的基本机器(dev vm上的客户端)上运行服务器时,它也可以工作.
当我在媒体中心PC上运行服务器时,它停止工作.例外是:
二进制流'0'不包含有效的BinaryHeader.可能的原因是序列化和反序列化之间的无效流或对象版本更改.
这三台PC都是x64 Windows 7机器.我正在使用TCPClient和TCPListener以及BinaryFormatter类来完成繁重的工作.
使用标准FileStream对象从文件中读取正在传输的数据.
如果在客户端我将缓冲区序列化为文件,那么内容(根据BeyondCompare)确实看起来确实有所不同?!?
我的对象上的所有字符串属性都是在setter中进行Base64编码并在getter中解码.
我可以发布代码,但我不确定问题所在的位置?有任何想法吗?
我使用序列化/去序列化技术.BinaryFormatter类.每次创建新程序集时,即使类结构相同,BinaryFormatter也不能反序列化二进制数据,但程序集版本不同.如果类结构保持不变,是否可以反序列化二进制缓冲区而不检查程序集版本?
Protobuf-net中存在AsReference选项,而BinaryFormatter是一个"图形序列化器",这使我认为BinaryFormatter不维护引用,并且它会复制每个对象.
但我做了一些测试,发现即使对于递归引用,单个BinaryFormatter Serialize()或Deserialize()调用中的所有引用都会被维护.
我可以确认BinaryFormatter确实维护引用吗?这与Protobuf-net有何不同?好像我理解"图形序列化"不正确?我还应该注意什么?
提前致谢.
本书CLR Via C#介绍了一种通过二进制序列化克隆对象的简单方法.
它指定StreamingContextStates.Clone何时创建BinaryFormatter类似:
var formatter = new BinaryFormatter
{
Context = new StreamingContext(StreamingContextStates.Clone)
};
Run Code Online (Sandbox Code Playgroud)
文档StreamingContextStates.Clone说它
指定正在克隆对象图.用户可以假设克隆的图形将继续存在于同一进程中,并且可以安全地访问句柄或对非托管资源的其他引用.
很公平 - 但我真的不知道这实际意味着什么.这实际上以什么方式改变了行为BinaryFormatter?任何人都可以列出使用此标志的具体效果吗?
我需要将大量的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)
这很慢.
微软警告不要使用BinaryFormatter(他们写道没有办法保证反序列化的安全)。
应用程序应尽快停止使用 BinaryFormatter,即使它们认为正在处理的数据是值得信赖的。
我不想使用基于XML或Json的解决方案(这是他们所指的)。我担心文件大小和保留对象图。
如果我要编写自己的方法来遍历我的对象图并将对象转换为二进制,那么可以安全地制作它,还是从二进制转换为特殊内容使其本质上比文本更危险?
binaryformatter ×10
c# ×8
.net ×3
arrays ×1
exception ×1
obfuscation ×1
performance ×1
protobuf-net ×1
reference ×1