3

WCF (数 GB)を介して大量のデータを送信しようとしています。Streams を使用して読み取り中にファイルを圧縮したいのですが、DeflateStream には 2 つのモードがあるようです。

  • 圧縮 (ストリームに書き込みます)
  • 解凍 (ストリームを読み取ります)

私の場合、これらのモードはどれも機能しません。ディスクから圧縮されていないファイルを読み取り、WCF を介して圧縮されたストリームを返したいと考えています。

そうする方法はありますか、それとも一時ファイル (または MemoryStream) を使用する必要がありますか?

欠落している機能ですか、それとも何らかの理由で不可能ですか?

4

6 に答える 6

3

ファイルの読み取り中に圧縮しようとしているようです。deflatestream の書き込み方法では、書き込みの一部として圧縮を行う必要があります。ディスクから読み取っているストリームではなく、ワイヤ経由で送信しているストリームをラップしてみてください。それらが同じ場合は、中間ストリームが必要です。

于 2012-05-09T16:23:03.110 に答える
3

これらのメソッドを使用して、バイト配列を圧縮および解凍してみてください。

    private static byte[] Compress(byte[] data)
    {
        byte[] retVal;
        using (MemoryStream compressedMemoryStream = new MemoryStream())
        {
            DeflateStream compressStream = new DeflateStream(compressedMemoryStream, CompressionMode.Compress, true);
            compressStream.Write(data, 0, data.Length);
            compressStream.Close();
            retVal = new byte[compressedMemoryStream.Length];
            compressedMemoryStream.Position = 0L;
            compressedMemoryStream.Read(retVal, 0, retVal.Length);
            compressedMemoryStream.Close();
            compressStream.Close();
        }
        return retVal;
    }



    private static byte[] Decompress(byte[] data)
    {
        byte[] retVal;
        using (MemoryStream compressedMemoryStream = new MemoryStream())
        {
            compressedMemoryStream.Write(data, 0, data.Length);
            compressedMemoryStream.Position = 0L;
            MemoryStream decompressedMemoryStream = new MemoryStream();
            DeflateStream decompressStream = new DeflateStream(compressedMemoryStream, CompressionMode.Decompress);
            decompressStream.CopyTo(decompressedMemoryStream);
            retVal = new byte[decompressedMemoryStream.Length];
            decompressedMemoryStream.Position = 0L;
            decompressedMemoryStream.Read(retVal, 0, retVal.Length);
            compressedMemoryStream.Close();
            decompressedMemoryStream.Close();
            decompressStream.Close();
        }
        return retVal;
}
于 2012-05-09T16:33:41.010 に答える
2

次のようなものが必要です。

public void CompressData(Stream uncompressedSourceStream, Stream compressedDestinationStream)
{
    using (DeflateStream compressionStream = new DeflateStream(compressedDestinationStream, CompressionMode.Compress))
    {
        uncompressedSourceStream.CopyTo(compressionStream);
    }
}

public void DecompressData(Stream compressedSourceStream, Stream uncompressedDestinationStream)
{
    using (DeflateStream decompressionStream = new DeflateStream(uncompressedDestinationStream, CompressionMode.Decompress))
    {
        compressedSourceStream.CopyTo(decompressionStream);
    }
}

using (FileStream sourceStream = File.OpenRead(@"C:\MyDir\MyFile.txt))
using (FileStream destinationStream = File.OpenWrite(@"C:\MyDir\MyCompressedFile.txt.cp"))
{
    CompressData(sourceStream, destinationStream)
}

また、非常に大きなものを転送できるようにするには、アプリケーションの .config ファイルで WCF 設定を変更する必要がある場合があることに注意してください。

于 2012-05-09T16:18:21.540 に答える
0

私はいつでもRead呼び出されるストリームを作成しようとしていました:

  • ソースファイルからデータのチャンクを読み取ります
  • DeflateStream 接続された MemoryStream にチャンクを書き込みます
  • MemoryStreamの内容をReadbufferパラメータにコピーします。

もちろん、両方のストリームのサイズが似ていないため、より困難になります。

最初に完全に圧縮しないと、結果の圧縮ファイルのサイズを予測する方法が見つからないため、最後にこのオプションを却下しました。

ただし、ファイルを読み取るとファイルサイズを予測できるため、別の実装でDeflateStream 可能になる可能性があります。

それが他の失われた魂を助けてくれることを願っています...

于 2012-05-09T18:00:50.773 に答える