You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VB6转.NET:多应用间自定义结构数组的跨程序序列化替代方案咨询

寻求.NET中跨应用的自定义结构数组文件存读的现代实现方案

我正在开发一款应用,使用包含多个变量及其他自定义结构子数组的自定义结构数组存储数据,需要实现该数据的文件存读功能。此前使用BinaryFormatter序列化方案时,在多个应用间加载保存的文件会出现问题,因此改用了VB6风格的FilePut/FileGet技术实现目标,现咨询是否有更现代的.NET代码写法。

当前使用的VB6风格实现代码

保存代码

'// Get file number
Dim fn As Integer = FreeFile()
'// Opens the file for binary write
FileOpen(fn, FileName, OpenMode.Binary, OpenAccess.Write)
'// Get persons count
Dim pc As Integer = Persons.GetUpperBound(0)
'// Write persons count
FilePut(fn, pc)
'// Write Persons
FilePut(fn, Persons)
'// Close the file
FileClose(fn)

加载代码

'// Get file number
Dim fn As Integer = FreeFile()
'// Opens the file for binary read
FileOpen(fn, FileName, OpenMode.Binary, OpenAccess.Read)
'// Get persons count
Dim pc As Integer
'// Read persons count
FileGet(fn, pc)
'// Prepare Persons array for it
Persons = Nothing
ReDim Persons(0 To pc)
'// Read Persons
FileGet(fn, Persons)
'// Close the file
FileClose(fn)

此前序列化方案的问题详情

测试用的两个应用StructureSaver_App_A和StructureSaver_App_B代码完全一致,但跨应用加载时报错:

  • 在App_A保存的文件,App_B加载时提示:System.Runtime.Serialization.SerializationException: 'Unable to find assembly 'StructureSaver_App_A, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.'
  • 在App_B保存的文件,App_A加载时提示:System.Runtime.Serialization.SerializationException: 'Unable to find assembly 'StructureSaver_App_B, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.'

同一应用内存读正常,以下是当时使用的序列化代码:

结构定义

'// Parent structure
<Serializable> Private Structure Parents
    Dim Name As String
    Dim Age As Integer
    Dim Kids() As Kids
End Structure
'// Kid structure
<Serializable> Private Structure Kids
    Dim Name As String
    Dim Age As Integer
    Dim GoesInScool As Boolean
End Structure
Private Persons() As Parents

保存代码

'// Gets BinaryFormatter
Dim BF As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter()
'// Makes new Memorystream
Dim MS As New System.IO.MemoryStream()
'// Serialize to Memorystream
BF.Serialize(MS, Persons)
'// Writes the content to file
My.Computer.FileSystem.WriteAllBytes(FileName, MS.GetBuffer(), False)

加载代码

'// Loads file to a byte()
Dim bytes As Byte() = My.Computer.FileSystem.ReadAllBytes(FileName)
'// Gets BinaryFormatter
Dim BF As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter()
'// Reads data
Persons = DirectCast(BF.Deserialize(New System.IO.MemoryStream(bytes)), Parents())

现代.NET替代方案

方案1:使用System.Text.Json(跨平台、无依赖)

Json是文本格式,可读性好,跨应用兼容性强,无需关心程序集信息。

首先调整结构为可访问级别(Private结构无法被Json序列化,建议改为Public),可添加特性控制字段名:

Public Structure Kids
    <JsonPropertyName("name")>
    Public Name As String
    <JsonPropertyName("age")>
    Public Age As Integer
    <JsonPropertyName("goes_to_school")>
    Public GoesInScool As Boolean
End Structure

Public Structure Parents
    <JsonPropertyName("name")>
    Public Name As String
    <JsonPropertyName("age")>
    Public Age As Integer
    <JsonPropertyName("kids")>
    Public Kids() As Kids
End Structure

保存代码

Dim jsonOptions As New JsonSerializerOptions With {
    .WriteIndented = True ' 可选,格式化输出便于阅读
}
Dim jsonString As String = JsonSerializer.Serialize(Persons, jsonOptions)
File.WriteAllText(FileName, jsonString)

加载代码

Dim jsonString As String = File.ReadAllText(FileName)
Persons = JsonSerializer.Deserialize(Parents())(jsonString)

方案2:使用protobuf-net(二进制格式,高性能)

protobuf是二进制序列化格式,体积小、速度快,跨语言跨应用兼容性好。

首先安装NuGet包protobuf-net,给结构添加序列化特性:

<ProtoContract>
Public Structure Kids
    <ProtoMember(1)>
    Public Name As String
    <ProtoMember(2)>
    Public Age As Integer
    <ProtoMember(3)>
    Public GoesInScool As Boolean
End Structure

<ProtoContract>
Public Structure Parents
    <ProtoMember(1)>
    Public Name As String
    <ProtoMember(2)>
    Public Age As Integer
    <ProtoMember(3)>
    Public Kids() As Kids
End Structure

保存代码

Using fs As New FileStream(FileName, FileMode.Create)
    Serializer.Serialize(fs, Persons)
End Using

加载代码

Using fs As New FileStream(FileName, FileMode.Open)
    Persons = Serializer.Deserialize(Parents())(fs)
End Using

方案3:手动二进制序列化(自定义格式,完全可控)

如果需要保持二进制格式且完全自定义,可以手动写入/读取每个字段,避免依赖旧API:

保存代码

Using writer As New BinaryWriter(File.Open(FileName, FileMode.Create))
    ' 写入人员数量
    writer.Write(Persons.Length)
    For Each parent In Persons
        ' 写入Parent字段
        writer.Write(parent.Name)
        writer.Write(parent.Age)
        ' 写入子数组长度
        writer.Write(parent.Kids.Length)
        For Each kid In parent.Kids
            writer.Write(kid.Name)
            writer.Write(kid.Age)
            writer.Write(kid.GoesInScool)
        Next
    Next
End Using

加载代码

Using reader As New BinaryReader(File.Open(FileName, FileMode.Open))
    Dim count As Integer = reader.ReadInt32()
    ReDim Persons(0 To count - 1)
    For i = 0 To count - 1
        Dim parent As New Parents()
        parent.Name = reader.ReadString()
        parent.Age = reader.ReadInt32()
        Dim kidCount As Integer = reader.ReadInt32()
        ReDim parent.Kids(0 To kidCount - 1)
        For j = 0 To kidCount - 1
            Dim kid As New Kids()
            kid.Name = reader.ReadString()
            kid.Age = reader.ReadInt32()
            kid.GoesInScool = reader.ReadBoolean()
            parent.Kids(j) = kid
        Next
        Persons(i) = parent
    Next
End Using

内容的提问来源于stack exchange,提问作者dreasi0n

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 02:50:25