2010-11-28 11 views
5

私はオブジェクトのカスタムシリアル化/逆シリアル化を行い、DeflateStreamsを使ってシリアル化されたデータを圧縮/解凍しようとしています。もともと私はもっと複雑なオブジェクトのためにこれをやっていましたが、問題を解明しようと努力しましたが、それがまだ残っているので困惑しました。ここで非直列化/直列化されるクラスは、次のとおりです。DeflateStreamsと共にカスタムシリアル化/逆シリアル化

[Serializable] 
    public class RandomObject : ISerializable 
    { 
     public String Name { get; set; } 
     public String SavePath { get; set; } 

     public RandomObject() 
     { 
     } 

     public RandomObject(String name, String savepath) 
     { 
      Name = name; 
      SavePath = savepath; 
     } 

     public RandomObject(SerializationInfo info, StreamingContext context) 
      : this(info.GetString("name"), info.GetString("savepath")) 
     { 
     } 
     [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)] 
     public void GetObjectData(SerializationInfo info, StreamingContext context) 
     { 
      info.AddValue("name", Name); 
      info.AddValue("savepath", SavePath); 
     } 
    } 

そして、ここでは、(動作するように思われる)、それをシリアル化することになっているコードです:

BinaryFormatter bf = new BinaryFormatter(); 
      using (MemoryStream ms = new MemoryStream()) 
      { 
       bf.Serialize(ms, profile); 
       using (DeflateStream ds = new DeflateStream(ms, CompressionMode.Compress)) 
       { 
        try 
        { 
         using (FileStream fs = File.Create(path)) 
         { 
          ds.Flush(); 
          Miscellaneous.CopyStream(ds.BaseStream, fs); 
          fs.Flush(); 
          fs.Close(); 
         } 
        } 
        catch (IOException e) 
        { 
         MessageBox.Show(e.Message); 
         success = false; 
        } 
        ds.Close(); 
       } 
       ms.Close(); 
      } 

そして、ここでは、逆シリアル化がされています

RandomObject profile = null; 
       using (FileStream fs = File.OpenRead(path)) 
       { 
        using (DeflateStream ds = new DeflateStream(fs, CompressionMode.Decompress)) 
        { 
         BinaryFormatter bf = new BinaryFormatter(); 
         ds.Flush(); 

         using (MemoryStream ms = new MemoryStream()) 
         { 
          Miscellaneous.CopyStream(ds.BaseStream, ms); 
          profile = bf.Deserialize(ms) as RandomObject; 
          profile.SavePath = path; 
          ms.Close(); 
         } 
         ds.Close(); 
        } 
        fs.Close(); 
       } 

今、問題に。 Deserializationは、メッセージ「{"オブジェクトのマップがありません '201326592'}でSerializationExceptionをスローします。どのようにトラブルシューティングを行うか、または問題の原因を正確に把握する方法はわかりません。非常に基本的な直列化は、BinaryFormatterのSerializeメソッドとDeserializeメソッドを同じMemoryStreamで実行するときに機能します。

私は両方のメソッドからDeflateStreamを削除しようとしましたが、それでも同じ問題があります。 MSDNや他の場所のサンプルを見ると、正しく動作しているように見えますが、例外メッセージのグーグルでは意味のある結果は得られません。

PS。あなたが見ることができるように、私はsrc.CopyTo(dest)を全く動かすことができないので、私は基本的なストリームコピー機であるMiscellaneous.CopyStream(src、dest)を使用するので、それに関するヒントも同様に歓迎されます。あなたがより密接にそれを見たい場合は

以下

は全体のVS2010のプロジェクトへのリンクです: http://www.diredumplings.com/SerializationTesting.zip

UPDATE:

The_Smallest:私はあなたが私に掲載圧縮方式を使用してみました連載:

BinaryFormatter bf = new BinaryFormatter(); 
      using (MemoryStream stream = new MemoryStream()) 
      { 
       bf.Serialize(stream, profile); 

       byte[] array = Compress(stream); 

       using (MemoryStream ms = new MemoryStream(array)) 
       { 
        using (FileStream fs = File.Create(path)) 
        { 
         ms.WriteTo(fs); 
         fs.Flush(); 
        } 
       } 
      } 

しかし、それということである、私が以前srcStream.CopyTo(destStream)としていた同じ問題を与えているようですストリームに書き込まれていないようです。結果は、ディスクに保存しようとすると0 KBのファイルになります。何か案は?

Pieter:デシリアライズメソッドからMemoryStreamを削除しました。以前と同じ機能を持つようです。しかし、あなたが提案した方法で直列化を実装する方法がわかりません。これはあなたが念頭に置いていたものですか?

BinaryFormatter bf = new BinaryFormatter(); 

      using (FileStream fs = File.Create(path)) 
      { 
       using (DeflateStream ds = new DeflateStream(fs, CompressionMode.Compress)) 
       { 
        bf.Serialize(ds, profile); 
        fs.Flush(); 
        ds.Close(); 
       } 
       fs.Close(); 
      } 

あなたのおかげで!

+0

そして、何ですがStream.Copyの問題?なぜそれは失敗するのですか? –

+0

どのようにそれを使用するにせよ、宛先ストリームは常に空ですが、私は何かばかげているかもしれません。 – vesz

答えて

1

私はあなたに例をあげて少し掘りました。

  1. LoadFromFile
    private static RandomObject LoadFromFile(string path) 
    { 
        try 
        { 
        var bf = new BinaryFormatter(); 
        using (var fileStream = File.OpenRead(path)) 
        using (var decompressed = new MemoryStream()) 
        { 
         using (var deflateStream = new DeflateStream(fileStream, CompressionMode.Decompress)) 
         deflateStream.CopyTo(decompressed); 
    
         decompressed.Seek(0, SeekOrigin.Begin); 
         var profile = (RandomObject)bf.Deserialize(decompressed); 
         profile.SavePath = path; 
         return profile; 
        } 
        } 
        catch (IOException e) 
        { 
        MessageBox.Show(e.Message); 
        return null; 
        } 
    } 
     
    
Loader.csで
  1. を交換し、次のようにSaver.csにSaveを交換してください:以下のプロジェクトの変更が参照
public static bool Save(RandomObject profile, String path) 
{ 
    try 
    { 
     var bf = new BinaryFormatter(); 
     using (var uncompressed = new MemoryStream()) 
     using (var fileStream = File.Create(path)) 
     { 
     bf.Serialize(uncompressed, profile); 
     uncompressed.Seek(0, SeekOrigin.Begin); 

     using (var deflateStream = new DeflateStream(fileStream, CompressionMode.Compress)) 
      uncompressed.CopyTo(deflateStream); 
     } 
     return true; 
    } 
    catch (IOException e) 
    { 
     MessageBox.Show(e.Message); 
     return false; 
    } 
} 
+0

これは別の答えです。これは、@ veszのプロジェクトに固有のものです。以前の回答とコードは、誰かに役立つ可能性があります。何かを圧縮または解凍しようとしています) –

+0

それを見ると、魅力的です。あなたの2つの異なる答えを必然的に組み合わせようとしていたが、何も働かなかった。どうもありがとう! – vesz

+0

以前は圧縮に問題がありました。だから、誰かの時間と神経を助け、救うことを試みた。 –

1

DeflateStreamにシリアル化する必要があります。これは、ベース(MemoryStream)ストリームではありません。

シリアル化の場合は、File.Createで始まります。そのストリームの周りにDeflateStreamを作成します。その後、DefaulteStreamにオブジェクトをシリアル化します。

デシリアライズの場合:MemoryStreamを作成せず、DeflateStreamから直接デシリアライズしてください。

MemoryStreamの追加は必要ありません。しかし、ファイルストリームから直接読み書きすることに問題がある場合は、MemoryStreamの代わりにDeflateStreamに書き込むようにserializeルーチンを変更してください。

それはあなたの問題を解決するはずです。ここで

+0

MemoryStreamの理由は、DeflateStreamだけを読んだり、そこに書き込んだり、シークしたりすることができないということでした。私は上記の変更を試して、それが動作するかどうかを確認します。ありがとう。 – vesz

+0

私はあなたのソリューションに質問の更新を掲載しましたが、私はまだそれを働かせる方法がわかりません。あなたの返信をありがとう! – vesz

+1

'bf.Serialize(ds.BaseStream、profile);を' bf.Serialize(ds、profile);に変更します。 'DeflateStream'は、あなたがinflate/deflate機能を得るためにコミュニケーションしなければならないストリームです。あなたは 'DeflateStream'の回りで作業し、代わりにベースストリームに書き込みます。これは 'DeflateStream'をまったく持っていないようなものです。 'DeflateStream'でストリームをラップするときは、元のストリームを無視し、代わりに' DeflateStream'を使うべきです。 –

1

あなたはこの後、あなたがのMemoryStream内(ないCompressStreamで)結果を持つことになり、MemoryStreamをへの書き込みCompressStreamに書くべき圧縮しながらストリームロジックに誤りがある はバイト

を圧縮して解凍する方法の例です
private static byte[] Compress(Stream stream) 
    { 
     using (var resultStream = new MemoryStream()) 
     { 
      using (var gzipStream = new DeflateStream(resultStream, CompressionMode.Compress)) 
       stream.CopyTo(gzipStream); 
      return resultStream.ToArray(); 
     } 
    } 

    private static byte[] Decompress(byte[] bytes) 
    { 
     using (var readStream = new MemoryStream(bytes)) 
     using (var resultStream = new MemoryStream()) 
     { 
      using (var gzipStream = new DeflateStream(readStream, CompressionMode.Decompress)) 
       gzipStream.CopyTo(resultStream); 
      return resultStream.ToArray(); 
     } 
    } 
+0

私はあなたのソリューションに質問の更新を掲載しましたが、私はまだそれを働かせる方法がわかりません。あなたの返信をありがとう! – vesz

関連する問題