61547


お世話になります。  
C#のDeflateStreamについて、下記の点を教えていただけないでしょうか。  
Streamをほとんど扱ったことがないので、おかしなことを書いていたり、いろいろ間違っている箇所があったりすると思いますが、その際は指摘いただけると幸いです。

## 1．DeflateStreamを用いた圧縮

DeflateStreamでバイト型配列をファイルに保存したいと考えています。  
この際、どのようなソースコードを作成すればよいのでしょうか。  
一応書きかけのソースコードを張っておきます。

[code]

    byte[] content = <何かのデータ>;
    using (Stream stream = new FileStream("test_compress.bin", FileMode.Create, FileAccess.Write)){
    using (MemoryStream ms = new MemoryStream(content)){
    using (DeflateStream ds = new DeflateStream(ms, CompressionMode.Compress, true)){
    //ここでファイルに書き込む？
    }
    }
    }
    
[/code]

## 2．DeflateStreamを用いた解凍

今度は上記と逆に、DeflateStreamでファイルに保存したデータを解凍して、バイト型配列に変換したいと考えています。  
MemoryStreamにコピーして、ToArrayで配列にしたらいい気はしているんですが、[MicrosoftのDeflateStreamのドキュメント](https://docs.microsoft.com/ja-
jp/dotnet/api/system.io.compression.deflatestream?view=netframework-4.8)によると、Lengthプロパティは利用できないと書かれており、一括では読み取れないようなんですが、どのようにしたらよいでしょうか。  
一応書きかけのソースコードを張っておきます。

[code]

    byte[] bytes;
    using (Stream stream = new FileStream("test_compress.bin", FileMode.Open, FileAccess.Read)){
    using (DeflateStream ds = new DeflateStream(stream, CompressionMode.Decompress)){
    using (MemoryStream ms = new MemoryStream(ds)){
    //ここでMemoryStreamの内容を受け取る必要がある？
    bytes = ms.ToArray();
    }
    }
    }
    
[/code]

以上、よろしくお願いいたします。


CC BY-SA 4.0
2019-12-18T10:01:34.590
61543
2019-12-19T22:54:15.550
29034
question
c#
C#のDeflateStreamについて


`DeflateStream`に対して`Write`を行うと圧縮されたデータが`BaseStream`に書き込まれます。

[code]

    byte[] content = <何かのデータ>;
    using (var ds = new DeflateStream(File.OpenWrite("test_compress.bin"), CompressionLevel.Optimal))
        ds.Write(content, 0, content.Length);
    
[/code]

逆に`DeflateStream`に対して`Read`を行うと`BaseStream`から読み込んだデータを展開して返してくれます。その際、ご指摘のように`Length`は使えません。ただし`Length`が使えなくとも終端は存在します。終端に達した場合、`Read`は長さ`0`を返します。とはいえ、この辺の面倒な処理は`CopyTo`に任せることができます。

[code]

    byte[] bytes;
    using (var ds = new DeflateStream(File.OpenRead("test_compress.bin"), CompressionMode.Decompress))
    using (var ms = new MemoryStream()) {
        ds.CopyTo(ms);
        bytes = ms.ToArray();
    }
    
[/code]

* * *

参考までに`CopyTo`は最終的に[このようなコード](https://github.com/microsoft/referencesource/blob/17b97365645da62cf8a49444d979f94a59bbb155/mscorlib/system/io/stream.cs#L225-L228)になっていて、愚直に`0`が返されるまで処理を繰り返しているだけです。

[code]

    byte[] buffer = new byte[bufferSize];
    int read;
    while ((read = Read(buffer, 0, buffer.Length)) != 0)
        destination.Write(buffer, 0, read);
    
[/code]


CC BY-SA 4.0
2019-12-18T12:53:08.653
61547
2019-12-19T22:54:15.550
2019-12-19T22:54:15.550
4236
4236
61543
answer