f# - 使用 FSPickler 将二进制反序列化为另一种类型

标签 f#

我有一个类型:

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/

相关文章:

F# NLog 配置文件

f# - 事件模式和成员约束

build - 我如何使用伪造的 "the f# way"创建一个 tar 存档

f# - 使用生成类型提供程序创建多个根类型

f# - 使用 F# 的默认编程风格

f# - 在部分应用上使用序列

javascript - F#/JavaScript 工具?

f# - Fsharp.Core 的正确版本

f# - F#Deedle访问行

f# - 在 F# API 中,是否有类似 Option.ofNull 的东西?