如何在 Python 中反序列化序列化的 C# 二进制文件?
How to deserialize a serialized C# binary file in Python?
我想反序列化 Visual Studio 2017 年用 C# 制作的二进制文件。
一个程序(C#) 序列化structs
不同类型的arrays
,另一个程序(C#) 反序列化文件。我想知道如何在 Python.
中做同样的工作
// ClassTickStruct.dll
namespace ClassTickStruct
{
[Serializable]
public struct struct_tick
{
public uint[] arr_currentIndex;
public string[] arr_currentType;
public DateTime[] arr_currentTime;
public struct_tick(byte size_index, byte size_type, byte size_time)
{
arr_currentIndex = new uint[size_index];
arr_currentType = new string[size_type];
arr_currentTime = new DateTime[size_time];
}
}
}
// How one program(C#) serializes structs
using (var fileStream = new FileStream(file.bin, FileMode.Append))
{
var bFormatter = new BinaryFormatter();
bFormatter.Serialize(fileStream, obj_struct);
}
// How the other program(C#) deserializes the file
List<struct_tick> list_read = new List<struct_tick>();
using (var fileStream = new FileStream("file.bin", FileMode.Open))
{
var bFormatter = new BinaryFormatter();
//bFormatter.Binder = new AllowAllAssemblyVersionsDeserializationBinder();
while (fileStream.Position != fileStream.Length)
{
list_read.Add((struct_tick)bFormatter.Deserialize(fileStream));
}
}
我参考了 Is there a way to read C# serialized objects into Python? 并尝试了 DirtyLittleHelper 的代码,但出现了一个错误:
data = serializer.Deserialize(reader)
System.Runtime.Serialization.SerializationException: 'tickReceiver, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' Assembly can't be found
location: System.Runtime.Serialization.Formatters.Binary.BinaryAssemblyInfo.GetAssembly()
location: System.Runtime.Serialization.Formatters.Binary.ObjectReader.GetType(BinaryAssemblyInfo assemblyInfo, String name)
location: System.Runtime.Serialization.Formatters.Binary.ObjectMap..ctor(String objectName, String[] memberNames, BinaryTypeEnum[] binaryTypeEnumA, Object[] typeInformationA, Int32[] memberAssemIds, ObjectReader objectReader, Int32 objectId, BinaryAssemblyInfo assemblyInfo, SizedArray assemIdToAssemblyTable)
location: System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectWithMapTyped(BinaryObjectWithMapTyped record)
location: System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectWithMapTyped(BinaryHeaderEnum binaryHeaderEnum)
location: System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run()
location: System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
location: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
location: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream)
当 C# 程序不共享结构的 dll 时,我遇到了同样的 Assembly can't be found
错误。然后我只是制作了一个 class 库(dll),其中包含结构并让程序引用它并且它们没有错误地工作。
# the whole Python code to deserialize the file
import clr
import System
#requires pythonnet installed -> pip install pythonnet
clr.AddReference(r"C:\Users\null\Desktop\RECEIVER\ClassTickStruct.dll")
from System.Runtime.Serialization.Formatters.Binary import BinaryFormatter
from System.IO import FileStream,FileMode,FileAccess,FileShare
filepath = "file.bin"
serializer = BinaryFormatter()
reader = FileStream(filepath, FileMode.Open, FileAccess.Read)
data = serializer.Deserialize(reader)
我认为不同之处在于它在 C# 中是 (struct_tick)bFormatter.Deserialize(fileStream)
而在 Python 中只是 serializer.Deserialize(reader)
。也许它需要一些关于 dll 中的结构的工作?
我想做的事实际上可以用 protobuf 实现。
// WRITE
using (var fileStream = new FileStream("file.bin", FileMode.Append))
{
Serializer.Serialize(fileStream, OBJ_struct);
}
// READ
using (var fileStream = new FileStream("file.bin", FileMode.Open))
{
struct_obj str = Serializer.Deserialize<struct_obj >(fileStream);
for (int num=0; num < str.arr_currentIndex.Length; num++)
{
listBox1.Items.Add(str.arr_currentIndex[num]);
}
}
感谢推荐protobuf的各位!
我想反序列化 Visual Studio 2017 年用 C# 制作的二进制文件。
一个程序(C#) 序列化structs
不同类型的arrays
,另一个程序(C#) 反序列化文件。我想知道如何在 Python.
// ClassTickStruct.dll
namespace ClassTickStruct
{
[Serializable]
public struct struct_tick
{
public uint[] arr_currentIndex;
public string[] arr_currentType;
public DateTime[] arr_currentTime;
public struct_tick(byte size_index, byte size_type, byte size_time)
{
arr_currentIndex = new uint[size_index];
arr_currentType = new string[size_type];
arr_currentTime = new DateTime[size_time];
}
}
}
// How one program(C#) serializes structs
using (var fileStream = new FileStream(file.bin, FileMode.Append))
{
var bFormatter = new BinaryFormatter();
bFormatter.Serialize(fileStream, obj_struct);
}
// How the other program(C#) deserializes the file
List<struct_tick> list_read = new List<struct_tick>();
using (var fileStream = new FileStream("file.bin", FileMode.Open))
{
var bFormatter = new BinaryFormatter();
//bFormatter.Binder = new AllowAllAssemblyVersionsDeserializationBinder();
while (fileStream.Position != fileStream.Length)
{
list_read.Add((struct_tick)bFormatter.Deserialize(fileStream));
}
}
我参考了 Is there a way to read C# serialized objects into Python? 并尝试了 DirtyLittleHelper 的代码,但出现了一个错误:
data = serializer.Deserialize(reader)
System.Runtime.Serialization.SerializationException: 'tickReceiver, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' Assembly can't be found
location: System.Runtime.Serialization.Formatters.Binary.BinaryAssemblyInfo.GetAssembly()
location: System.Runtime.Serialization.Formatters.Binary.ObjectReader.GetType(BinaryAssemblyInfo assemblyInfo, String name)
location: System.Runtime.Serialization.Formatters.Binary.ObjectMap..ctor(String objectName, String[] memberNames, BinaryTypeEnum[] binaryTypeEnumA, Object[] typeInformationA, Int32[] memberAssemIds, ObjectReader objectReader, Int32 objectId, BinaryAssemblyInfo assemblyInfo, SizedArray assemIdToAssemblyTable)
location: System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectWithMapTyped(BinaryObjectWithMapTyped record)
location: System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectWithMapTyped(BinaryHeaderEnum binaryHeaderEnum)
location: System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run()
location: System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
location: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
location: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream)
当 C# 程序不共享结构的 dll 时,我遇到了同样的 Assembly can't be found
错误。然后我只是制作了一个 class 库(dll),其中包含结构并让程序引用它并且它们没有错误地工作。
# the whole Python code to deserialize the file
import clr
import System
#requires pythonnet installed -> pip install pythonnet
clr.AddReference(r"C:\Users\null\Desktop\RECEIVER\ClassTickStruct.dll")
from System.Runtime.Serialization.Formatters.Binary import BinaryFormatter
from System.IO import FileStream,FileMode,FileAccess,FileShare
filepath = "file.bin"
serializer = BinaryFormatter()
reader = FileStream(filepath, FileMode.Open, FileAccess.Read)
data = serializer.Deserialize(reader)
我认为不同之处在于它在 C# 中是 (struct_tick)bFormatter.Deserialize(fileStream)
而在 Python 中只是 serializer.Deserialize(reader)
。也许它需要一些关于 dll 中的结构的工作?
我想做的事实际上可以用 protobuf 实现。
// WRITE
using (var fileStream = new FileStream("file.bin", FileMode.Append))
{
Serializer.Serialize(fileStream, OBJ_struct);
}
// READ
using (var fileStream = new FileStream("file.bin", FileMode.Open))
{
struct_obj str = Serializer.Deserialize<struct_obj >(fileStream);
for (int num=0; num < str.arr_currentIndex.Length; num++)
{
listBox1.Items.Add(str.arr_currentIndex[num]);
}
}
感谢推荐protobuf的各位!