2016-05-12 125 views
1

以下では、クラスオブジェクト "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をデシリアライズしようとすると、未処理の例外が「入力ストリームが有効なバイナリ形式ではありません」受け取ります。私はこれにかなり新しいので、どんな助けもありがとう!

答えて

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 
+0

私が期待していたように...私は必要以上に難しいものにしました。この魅力のように機能してくれた、素早い答えをありがとう!私はさらに属性を明確にしていないことをお詫びします! –

+0

私たちは皆、その時に良いアイデアのように思えるものがたくさんありますが、振り返ってみると半分ほど賢いようです。 – Plutonix

関連する問題