昨日、データベース同期テストをしていたとき、少しシリアライズとデシリアライズの技術を使いました。 テーブルのフィールドをエンティティクラスDiagramInfoに抽象化し、クライアントの新しいレコードをジェネリックコレクションに保存し、このジェネリックコレクションをシリアライズしてTCP経由でサーバーに送信し、TCPがデシリアライズしてからデータベースに書き込みます。 おそらくこの作戦のプロセスはこれでしょう。
シリアライズ:System.Runtime.Serialization.Iformatter クラスを使って、汎用コレクションをバイナリストリームにシリアライズします。 シリアル化されたコードの一部は以下の通りです:
- private void Seriable(List diagrams)
- {
- MemoryStream stream = new MemoryStream();
- IFormatter formater = new BinaryFormatter();
- formater.Serialize(stream, diagrams);
- stream.Flush();
- serializedData = stream.ToArray();
- stream.Close();
- }
コードをコピーします その後、TCPプロトコルで送信しますが、この部分は省略されます。
サーバーはデータを部分的に受信し、メモリストリームとして保存し、その後デシリアライズします。コードの一部は以下の通りです。
- do
- {
- bytesRead = stream.Read(responseBuffer, 0, bufferSize);
- memstream.Write(responseBuffer, 0, bytesRead);
- }
- while (bytesRead > 0);
- IFormatter formater = new BinaryFormatter();
- diagrams = (List)formater.Deserialize(memstream);
- stream.Close();
- memstream.Close();
- client.Close();
コードをコピーしますこの時点でクライアントとサーバーを起動してデータを同期すると、以下のエラーメッセージが表示されます。 エラー挙動:図 = (リスト)フォーマター。 Deserialize(memstream); 文字通り:変換が完了する前にストリームの終わりに遭遇しました。 2. 解Google検索の結果、以下の誤りの可能性に答えた人がいました:1. シリアライゼーションとデシリアライズの種類は異なり、ここでは除外できます。 2. シリアル化時にストリームをクリアするバッファがなく、Flush()メソッドは使用されず、ここでも除外できます。 3. デシリアライズ前の受信プロセスのバッファサイズが十分でない場合もありますが、問題はないと思います。デシリアライズは取得ストリームの後に行われるもので、バッファのサイズとは関係ないはずです。個人的な意見ですが、試したことはありません。 4. デシリアライズの前に追加ストレム。 位置=0。 (Streamはデシリアライズされるストリームで、実際にはmemstreamです) テストの結果、4つ目は私のプログラムに合うかもしれません。 では、なぜこのような現象が起こるのでしょうか?デバッグの一段階で、メモリストリームを観察してください。 Postionの値は変化し、書き込み操作が行われるたびに値が末尾を指していることが判明し、これがプログラムがそのようなエラーを報告する理由を説明しています。 しかし、なぜデシリアライゼーション関数が(Deserialize)を、デフォルトでストリーム全体をデシリアライズするのではなく、ポジトンの位置から始めるのですか?
|