13

コードが期待どおりに実行されない理由を理解しようとしています。GZipStream を作成し、オブジェクトを圧縮ファイルとしてハード ドライブに保存しますが、保存されるファイルは常に 0 バイトです。

GZipStream を使用してファイルを保存する方法はわかりましたが、私の質問はその方法ではありません。私の質問は、純粋に、このコードが 0 バイトを節約する理由 (または FileStream が機能し、メモリが機能しない理由) です。

private void BegingCompression()
{
    var bytes = File.ReadAllBytes(this.fileName);
    using (MemoryStream ms = new MemoryStream(bytes))
    {
        ms.ReadByte();
        using (FileStream fs =new FileStream(this.newFileName, FileMode.CreateNew))
        using (GZipStream zipStream = new GZipStream(ms, CompressionMode.Compress, false))
        {
            zipStream.Write(bytes, 0, bytes.Length);
        }
    }
}

ソースコードに関しては、(this.fileName = c:\Audio.wavしかし、試してみました)newFileNamec:\Audio.wav.gzc:\audio.gz

4

4 に答える 4

17
  • bytes圧縮するデータが既に あるため、MemoryStream は必要ありません。
  • ms.ReadByte()使用しないでください。
  • zipStream出力ファイル ストリームを作成するときは、使用する必要があります。

これを試して:

var bytes = File.ReadAllBytes(this.fileName);
using (FileStream fs =new FileStream(this.newFileName, FileMode.CreateNew))
using (GZipStream zipStream = new GZipStream(fs, CompressionMode.Compress, false))
{
     zipStream.Write(bytes, 0, bytes.Length);
}

編集

ファイル ストリームに書き込みを行わないため、元のコードでは長さ 0 のファイルが作成されます。

于 2013-01-12T19:40:22.887 に答える
11

GzipStreamまたは名前空間DeflateStreamから使用すると、コンストラクターで指定したものが圧縮用に書き込まれdecompressionから読み取られます。System.IO.CompressionStream

ここでデータを圧縮しようとしているのでMemoryStream、圧縮しようとしているのではなく、データ ソースとして使用しているため、 を使用するのは正しくありません。したがって、あなたMemoryStreamが入力Streamになり、FileStreamが出力になります。

汎用性とアプリケーションがはるかに多いためMemoryStream、未加工のデータ ソースとして使用することを強くお勧めします ( 、、など)。byte[]StreamFileStreamNetworkStreamCryptoStream

async/awaitパターンを使用した例を次に示します。

public static async Task CompressToFileAsync(byte[] buffer, 
                                             string outputFile)
{
  using (var inputStream = new MemoryStream(buffer))
    await CompressToFileAsync(inputStream, outputFile);
}

public static async Task CompressToFileAsync(Stream inputStream, 
                                             string outputFile)
{
  using (var outputStream = File.Create(outputFile))
  using (var gzip = new GZipStream(outputStream, CompressionMode.Compress))
  {
    await inputStream.CopyToAsync(gzip);
    gzip.Close();
  }
}

public static async Task<MemoryStream> DecompressFromFileAsync(string inputFile)
{
  var outputStream = new MemoryStream();

  using (var inputStream = File.Open(inputFile, FileMode.Open, FileAccess.Read, FileShare.Read))
  using (var gzip = new GZipStream(inputStream, CompressionMode.Decompress))
  {
    await gzip.CopyToAsync(outputStream);

    gzip.Close();
    inputStream.Close();

    // After writing to the MemoryStream, the position will be the size
    // of the decompressed file, we should reset it back to zero before returning.
    outputStream.Position = 0;
    return outputStream;
  }
}

注:入力または出力GzipStream.Close()を閉じる前に、必ず呼び出してください。閉じる/破棄するときに最終的なバッファーのフラッシュを行います。入力または出力が最初に閉じられた場合、そうしようとすると例外がスローされます。(これは にも当てはまります) StreamDeflateStream

于 2013-01-12T20:40:16.503 に答える
3
why FileStream works and memory doesn't

MemoryStream のバッキング ストアはハード ドライブではなく RAM メモリであるためです。したがって、MemoryStreamオブジェクトをGZipStreamコンストラクターに渡すと、gzip は RAM に保存されます。

このコードで:

using (FileStream fs =new FileStream(this.newFileName, FileMode.CreateNew))

新しい FileStream を作成していますが、使用していません。この FIleStream を使用して gzip を保存するには、それをGZipStreamコンストラクターに渡して、バッキング ストアをハード ドライブにする必要があります。

于 2013-01-12T19:38:45.103 に答える