使用 FSPickler 将二进制反序列化为另一种类型
binary deserialization to another type with FSPickler
我有一个类型:
type T =
{
a: int
b: string
}
和一个名为 'myArray' 的 T 类型数组。
我想用 FSPickler 序列化 myArray:
FsPickler.CreateBinarySerializer().Pickle myArray
但是在 pickle 文件中,类型 T 是完全合格的,如果我将它重新定位到另一个 app/namespace,那么 unpickle 就会失败。
我在 FSPickler git 上询问过,但我收到的答案是:
Per documentation in http://mbraceproject.github.io/FsPickler/ the serializer is not > designed with version tolerance in mind. That being said, it should be possible to work > around that issue by providing a custom implementation of the ITypeNameConverter interface.
好的,很公平。
但是,该文档提供的示例清楚地由了解 picklers 的人编写,并且适用于也了解 picklers 的其他人。
谁能post举个例子,我可以为这个基本案例制作自定义序列化器/反序列化器?从文档中,我看到所有奇怪的情况都是在假设 reader 知道如何使用 FSPickler 制作基本序列化程序的情况下解释的。
或者,也许我在文档中漏掉了一些非常明显的东西,如果我看到它,我会很高兴地认出它:)
文档在这里:https://mbraceproject.github.io/FsPickler/tutorial.html
而且,对于上下文,我正在处理 24 GB 的数据(显然比这个例子中的类型更复杂),所以速度就是一切,而 FSPickler 看起来相当快。
似乎根本没有关于此的任何文档,但我设法拼凑出了一些有用的东西。我发现的技巧是使用一个非常简单的转换器,它始终使用相同的类型名称,如下所示:
let converter =
{
new ITypeNameConverter with
member this.OfSerializedType(typeInfo) =
{ typeInfo with Name = "dummy" } // always use dummy type name
member this.ToDeserializedType(typeInfo) =
typeInfo
}
然后我们可以像这样腌制 T
的数组:
type T =
{
a: int
b: string
}
let tArray =
[|
{ a = 1; b = "one" }
{ a = 2; b = "two" }
{ a = 3; b = "three" }
|]
let serializer = FsPickler.CreateBinarySerializer(typeConverter = converter)
let bytes = serializer.Pickle(tArray)
然后我们可以将它分解为具有相同结构的不同类型的数组(“duck typing”):
type U =
{
a: int
b: string
}
let uArray = serializer.UnPickle<U[]>(bytes)
我不知道这是否是“正确”的做法。我发现 ITypeNameConverter
的行为并不像我预期的那样。特别是,似乎 OfSerializedType
在 pickling 和 unpickling 期间都被调用,而 ToDeserializedType
根本没有被调用。也许我遗漏了一些重要的东西。
我有一个类型:
type T =
{
a: int
b: string
}
和一个名为 'myArray' 的 T 类型数组。
我想用 FSPickler 序列化 myArray:
FsPickler.CreateBinarySerializer().Pickle myArray
但是在 pickle 文件中,类型 T 是完全合格的,如果我将它重新定位到另一个 app/namespace,那么 unpickle 就会失败。
我在 FSPickler git 上询问过,但我收到的答案是:
Per documentation in http://mbraceproject.github.io/FsPickler/ the serializer is not > designed with version tolerance in mind. That being said, it should be possible to work > around that issue by providing a custom implementation of the ITypeNameConverter interface.
好的,很公平。
但是,该文档提供的示例清楚地由了解 picklers 的人编写,并且适用于也了解 picklers 的其他人。
谁能post举个例子,我可以为这个基本案例制作自定义序列化器/反序列化器?从文档中,我看到所有奇怪的情况都是在假设 reader 知道如何使用 FSPickler 制作基本序列化程序的情况下解释的。
或者,也许我在文档中漏掉了一些非常明显的东西,如果我看到它,我会很高兴地认出它:)
文档在这里:https://mbraceproject.github.io/FsPickler/tutorial.html
而且,对于上下文,我正在处理 24 GB 的数据(显然比这个例子中的类型更复杂),所以速度就是一切,而 FSPickler 看起来相当快。
似乎根本没有关于此的任何文档,但我设法拼凑出了一些有用的东西。我发现的技巧是使用一个非常简单的转换器,它始终使用相同的类型名称,如下所示:
let converter =
{
new ITypeNameConverter with
member this.OfSerializedType(typeInfo) =
{ typeInfo with Name = "dummy" } // always use dummy type name
member this.ToDeserializedType(typeInfo) =
typeInfo
}
然后我们可以像这样腌制 T
的数组:
type T =
{
a: int
b: string
}
let tArray =
[|
{ a = 1; b = "one" }
{ a = 2; b = "two" }
{ a = 3; b = "three" }
|]
let serializer = FsPickler.CreateBinarySerializer(typeConverter = converter)
let bytes = serializer.Pickle(tArray)
然后我们可以将它分解为具有相同结构的不同类型的数组(“duck typing”):
type U =
{
a: int
b: string
}
let uArray = serializer.UnPickle<U[]>(bytes)
我不知道这是否是“正确”的做法。我发现 ITypeNameConverter
的行为并不像我预期的那样。特别是,似乎 OfSerializedType
在 pickling 和 unpickling 期间都被调用,而 ToDeserializedType
根本没有被调用。也许我遗漏了一些重要的东西。