【问题标题】:Input stream is not a valid binary format.输入流不是有效的二进制格式。
【发布时间】:2016-05-12 20:24:20
【问题描述】:

下面我将类对象“ListViewCereal”序列化为内存流,然后将内存流的缓冲区存储到访问数据库列中。

    If chkSerialize.Checked = True Then
        Dim cereal As New ListViewCereal                                        'class used to store item list views
        Dim bin_form As New BinaryFormatter                                     'used to serialize and deserialize objects
        Dim file_stream As New MemoryStream                                     'serialization stream
        Dim report_row As DataRow = mycallerPreview.previewInst.SerializedDataDataSet.SavedReportLayouts.NewRow

        cereal.prep_cereal(MoveItemListViewClass1, MoveItemListViewClass2, MoveItemListViewClass3)
        bin_form.Serialize(file_stream, cereal)
        builder.Clear()

        'extract buffer and append string representation of each bit to StringBuilder "builder"
        file_stream.Position = 0
        Dim byteArray() As Byte = file_stream.GetBuffer()
        For Each bit As Byte In byteArray
            builder.Append(bit.ToString)
        Next

        report_row("Serialized Data") = builder.ToString 'column storing string rep. of buffer

        builder.Clear()
        builder.Append(txtYear.Text.ToString).Append("-").Append(txtVendor.Text.ToString).Append("-").Append(txtReport.Text.ToString)
        report_row("Report Name") = builder.ToString
        report_row("User Name") = ""                        'TODO:setup login window to track users
        mycallerPreview.previewInst.SerializedDataDataSet.SavedReportLayouts.AddSavedReportLayoutsRow(report_row)
        mycallerPreview.previewInst.TableAdapterManager.UpdateAll(mycallerPreview.previewInst.SerializedDataDataSet)

        file_stream.Close()
        file_stream.Dispose()
        mycallerPreview.Show()
        mycallerPreview.previewInst.Close()
        mycallerPreview.previewInst = Nothing
    Else
        mycallerPreview.Show()
        mycallerPreview.previewInst.Close()
        mycallerPreview.previewInst = Nothing
    End If

在下面的代码中,我尝试通过引用数据库行/列来反序列化类。

       If cmbSavedLayouts.SelectedIndex <> -1 Then

        Dim rep_row As DataRow = mycallerSelect2.select_secInst.SerializedDataDataSet.SavedReportLayouts.NewRow
        rep_row = mycallerSelect2.select_secInst.SerializedDataDataSet.SavedReportLayouts.Rows(cmbSavedLayouts.SelectedIndex)
        Dim str As String = rep_row("Serialized Data").ToString
        Dim temp As Byte() = str.Select(AddressOf Byte.Parse).ToArray
        Dim file_stream As New MemoryStream

        file_stream.Write(temp, 0, temp.Count)
        file_stream.Position = 0
        Dim cereal_views As ListViewCereal = CType(bin_form.Deserialize(file_stream), ListViewCereal)
    End If

当我尝试反序列化 file_stream 时,我收到未处理的异常“输入流不是有效的二进制格式”。我对此很陌生,因此感谢您的帮助!

【问题讨论】:

    标签: database vb.net ms-access serialization deserialization


    【解决方案1】:

    您有几个错误。首先是这样的:

    Dim byteArray() As Byte = file_stream.GetBuffer()
    

    缓冲区总是大于存储的数据;有时要大得多(70-80%!),所以应该使用ToArray() 来获取数据。接下来是这个:

    For Each bit As Byte In byteArray
        builder.Append(bit.ToString)
    Next
    

    我不知道builder 是什么,但它看起来像StringBuilder。保存byteArray 本身并避免任何其他转换是最简单的。但是对于字符串存储,您应该使用 Base64 字符串,该字符串可以轻松转换回字节数组:

    Dim serData As String = Convert.ToBase64String(memStrm.ToArray())
    

    所以,序列化和存储应该是这样的:

    Dim B64Data As String
    Using ms As New MemoryStream
        Dim bf As New BinaryFormatter
        bf.Serialize(ms, cereal)
        B64Data = Convert.ToBase64String(ms.ToArray())
    End Using
    
    ' no idea what this is, just copied it
    report_row("Serialized Data") = B64Data 
    

    反序列化将是相反的:

    ' get data, unbox
    Dim B64Data = dr.Field(Of String)("Serialized Data")
    
    ' I have no idea if these types are correct, just copying them
    Dim cereal_views As ListViewCereal
    Using ms As New MemoryStream(Convert.FromBase64String(B64Data ))
        Dim bf As New BinaryFormatter
        cereal_views = CType(bf.Deserialize(ms), ListViewCereal)
    End Using
    

    【讨论】:

    • 正如我所料...我让事情变得比需要的更困难。感谢您的快速回答,这就像一个魅力!我也为没有更多地澄清属性而道歉!
    • 我们都这样做 - 很多当时看起来不错的想法,现在回想起来似乎太聪明了。
    猜你喜欢
    • 1970-01-01
    • 2011-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-07
    • 2011-09-29
    • 1970-01-01
    • 2020-10-16
    相关资源
    最近更新 更多