我有一个类型:
type T =
{
a: int
b: string
}
和一个名为“myArray”的 T 类型数组。
我想用 FSPickler 序列化 myArray:
FsPickler.CreateBinarySerializer().Pickle myArray
但是在 pickle 文件中,类型 T 是完全限定的,如果我将它重新定位到另一个应用程序/命名空间,那么 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 的其他人。
任何人都可以发布一个示例,我可以为这个基本案例制作自定义序列化器/反序列化器吗?从文档中,我看到所有奇怪的案例都是在假设读者知道如何使用 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
}
然后我们可以像这样 pickle 一个 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)
然后我们可以将它分解为具有相同结构的不同类型的数组(“鸭子类型”):
type U =
{
a: int
b: string
}
let uArray = serializer.UnPickle<U[]>(bytes)
我不知道这是否是“正确”的做法。我发现 ITypeNameConverter
的行为并不像我预期的那样。特别是,似乎 OfSerializedType
在 pickling 和 unpickling 期间都被调用,而 ToDeserializedType
根本没有被调用。也许我遗漏了一些重要的东西。
关于f# - 使用 FSPickler 将二进制反序列化为另一种类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70369176/