1. ホーム
  2. c#

[解決済み】System.IO.Compressionを使用してメモリ内にZIPアーカイブを作成する。

2022-04-08 02:18:55

質問

シンプルなデモ用テキストファイルでZIPアーカイブを作成しようとしています。 MemoryStream を次のようにします。

using (var memoryStream = new MemoryStream())
using (var archive = new ZipArchive(memoryStream , ZipArchiveMode.Create))
{
    var demoFile = archive.CreateEntry("foo.txt");

    using (var entryStream = demoFile.Open())
    using (var streamWriter = new StreamWriter(entryStream))
    {
        streamWriter.Write("Bar!");
    }

    using (var fileStream = new FileStream(@"C:\Temp\test.zip", FileMode.Create))
    {
        stream.CopyTo(fileStream);
    }
}

このコードを実行すると、アーカイブファイル自体は作成されるのですが foo.txt が表示されない。

しかし MemoryStream を直接ファイルストリームに置き換えると、アーカイブは正しく作成されます。

using (var fileStream = new FileStream(@"C:\Temp\test.zip", FileMode.Create))
using (var archive = new ZipArchive(fileStream, FileMode.Create))
{
    // ...
}

を使用することは可能でしょうか? MemoryStream を使わずにZIPアーカイブを作成します。 FileStream ?

解決方法は?

ありがとうございます。 ZipArchiveが不正なZIPファイルを作成する を、手に入れました。

using (var memoryStream = new MemoryStream())
{
   using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
   {
      var demoFile = archive.CreateEntry("foo.txt");

      using (var entryStream = demoFile.Open())
      using (var streamWriter = new StreamWriter(entryStream))
      {
         streamWriter.Write("Bar!");
      }
   }

   using (var fileStream = new FileStream(@"C:\Temp\test.zip", FileMode.Create))
   {
      memoryStream.Seek(0, SeekOrigin.Begin);
      memoryStream.CopyTo(fileStream);
   }
}

を呼び出す必要があることが示されました。 DisposeZipArchive Amir が言うように、アーカイブにチェックサムのような最終バイトを書き込んで、アーカイブを完成させるからだと思われます。しかし、ストリームを閉じて再利用できるようにするためには、アーカイブに true の3番目のパラメータとして ZipArchive .