2012-05-15 10 views
16

Compression.DeflateStreamを使用してストリームを圧縮および解凍しようとしています。以下のコードは私のストリームを110バイトの長さの配列に圧縮するので、圧縮は正しく動作しているようです。ただし、圧縮解除されたStreamを読み取ると、空の文字列が返されます。Compression.DeflateStreamでストリームを圧縮および解凍

class Program 
{ 
    static void Main(string[] args) 
    { 
     // Compress a random string value 
     string value = Path.GetRandomFileName(); 
     byte[] compressedBytes; 

     using (var writer = new StreamWriter(new MemoryStream())) 
     { 
      writer.Write(value); 
      writer.Flush(); 
      writer.BaseStream.Position = 0; 

      compressedBytes = Compress(writer.BaseStream); 
     } 

     // Decompress compressed bytes 
     Stream decompressedStream = Decompress(compressedBytes); 
     // here already applies: decompressedStream.Length == 0 

     using (var reader = new StreamReader(decompressedStream)) 
     { 
      string decompressedValue = reader.ReadToEnd(); 

      if (value == decompressedValue) 
       Console.WriteLine("Success"); 
      else 
       Console.WriteLine("Failed"); 
     } 
    } 

    private static byte[] Compress(Stream input) 
    { 
     using (var compressStream = new MemoryStream()) 
     using (var compressor = new DeflateStream(compressStream, CompressionMode.Compress)) 
     { 
      input.CopyTo(compressor); 
      return compressStream.ToArray(); 
     } 
    } 

    private static Stream Decompress(byte[] input) 
    { 
     var output = new MemoryStream(); 

     using (var compressStream = new MemoryStream(input)) 
     using (var decompressor = new DeflateStream(compressStream, CompressionMode.Decompress)) 
      decompressor.CopyTo(output); 

     output.Position = 0; 
     return output; 
    } 
} 

誰でも私にこのことを教えてもらえますか? 多くのありがとうございます。

答えて

25

あなたCompress機能修正:

private static byte[] Compress(Stream input) 
{ 
    using(var compressStream = new MemoryStream()) 
    using(var compressor = new DeflateStream(compressStream, CompressionMode.Compress)) 
    { 
     input.CopyTo(compressor); 
     compressor.Close(); 
     return compressStream.ToArray(); 
    } 
} 

圧縮ストリームは、結果のバイト配列を返す前にフラッシュされませんでした。

+0

これは機能します。多くのありがとう – greijner

+3

'Close'ではなく' Flush'を呼び出すと動作しません。内部的に 'Flush'を呼び出す' Close'はこれがなぜ機能するのかと思っていました。 –

+4

@Luke:[DeflateStream.Flush() 'のドキュメント](https://msdn.microsoft.com/en-us/library/system.io.compression.deflatestream.flush(v = vs.110) .aspx):_ "このメソッドの現在の実装は、内部バッファをフラッシュしません。オブジェクトが破棄されると内部バッファがフラッシュされます。" _これがデザインである理由について、 'Stream.Flush()'は内部バッファリングをフラッシュしますが、デフレートされたストリームは_end_にあることがわかるまでファイナライズすることはできません。これはストリームが閉じられたときにのみ可能です。 –

9

ストリームを閉じてください:

class Program 
{ 
    static void Main(string[] args) 
    { 
     // Compress a random string value 
     string value = DateTime.Now.ToLongTimeString(); 
     byte[] compressedBytes; 

     using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(value))) 
     { 
      compressedBytes = Compress(stream); 
     } 


     // Decompress compressed bytes 
     using (var decompressedStream = Decompress(compressedBytes)) 
     using (var reader = new StreamReader(decompressedStream)) 
     { 
      string decompressedValue = reader.ReadToEnd(); 

      if (value == decompressedValue) 
       Console.WriteLine("Success"); 
      else 
       Console.WriteLine("Failed"); 
     } 
    } 

    public static byte[] Compress(Stream input) 
    { 
     using (var compressedStream = new MemoryStream()) 
     using (var zipStream = new GZipStream(compressedStream, CompressionMode.Compress)) 
     { 
      input.CopyTo(zipStream); 
      zipStream.Close(); 
      return compressedStream.ToArray(); 
     } 
    } 

    public static Stream Decompress(byte[] data) 
    { 
     var output = new MemoryStream(); 
     using(var compressedStream = new MemoryStream(data)) 
     using(var zipStream = new GZipStream(compressedStream, CompressionMode.Decompress)) 
     { 
      zipStream.CopyTo(output); 
      zipStream.Close(); 
      output.Position = 0; 
      return output; 
     } 
    } 
} 
+1

私は同じcompress Decompress関数を使用しています。解凍は正常に動作しますが、返されたStreamオブジェクトが私に与えます。閉じたストリームにアクセスできません。私はそれに取り組もうとしている間にメッセージを送ります。圧縮解除機能の前に同じコードが動作していました。何か案が? – afr0

4

あなたのすべてが「使用」配置し、終値は追加閉じる()は必要ありませんその手段をストリームすることを忘れてしまったので、これらすべての答えは理想的なフォームから遠く離れています。私は理想的なコードは次のようになると思います:

public static class CompressionHelper 
{ 
    public static byte[] Compress(byte[] data) 
    { 
     byte[] compressArray = null; 
     try 
     { 
      using (MemoryStream memoryStream = new MemoryStream()) 
      { 
       using (DeflateStream deflateStream = new DeflateStream(memoryStream, CompressionMode.Compress)) 
       { 
        deflateStream.Write(data, 0, data.Length); 
       } 
       compressArray = memoryStream.ToArray(); 
      } 
     } 
     catch (Exception exception) 
     { 
      // do something ! 
     } 
     return compressArray; 
    } 

    public static byte[] Decompress(byte[] data) 
    { 
     byte[] decompressedArray = null; 
     try 
     { 
      using (MemoryStream decompressedStream = new MemoryStream()) 
      { 
       using (MemoryStream compressStream = new MemoryStream(data)) 
       { 
        using (DeflateStream deflateStream = new DeflateStream(compressStream, CompressionMode.Decompress)) 
        { 
         deflateStream.CopyTo(decompressedStream); 
        } 
       } 
       decompressedArray = decompressedStream.ToArray(); 
      } 
     } 
     catch (Exception exception) 
     { 
      // do something ! 
     } 

     return decompressedArray; 
    } 
} 
関連する問題