web-dev-qa-db-ja.com

C#でメモリ内のファイルからZipArchiveを作成する方法

メモリ内の(実際にはディスク上ではない)ファイルからZipArchiveを作成することはどういうわけか可能ですか?.

以下はユースケースです:複数のファイルがIEnumerable<HttpPostedFileBase>変数。 ZipArchiveを使用して、これらすべてのファイルをまとめて圧縮します。問題は、ZipArchiveCreateEntryFromFileのみを許可することです。これは、ファイルへのパスを期待します。

質問:「ストリーム」を使用してZipArchiveに「エントリ」を作成し、zip内のファイルのコンテンツを直接挿入する方法はありますか?

最初にファイルを保存し、(保存されたファイルのパスから)Zipを作成してから、個々のファイルを削除したくありません。

ここで、attachmentFilesIEnumerable<HttpPostedFileBase>

using (var ms = new MemoryStream())
{
    using (var zipArchive = new ZipArchive(ms, ZipArchiveMode.Create, true))
    {
        foreach (var attachment in attachmentFiles)
        {
            zipArchive.CreateEntryFromFile(Path.GetFullPath(attachment.FileName), Path.GetFileName(attachment.FileName),
                                CompressionLevel.Fastest);
        }
    }
    ...
}
16
Flair

はい、これは ZipArchive.CreateEntry メソッドを使用して行うことができます。@ AngeloReisがコメントで指摘され、少し異なる問題について ここ で説明されています。

コードは次のようになります。

using (var ms = new MemoryStream())
{
    using (var zipArchive = new ZipArchive(ms, ZipArchiveMode.Create, true))
    {
        foreach (var attachment in attachmentFiles)
        {
            var entry = zipArchive.CreateEntry(attachment.FileName, CompressionLevel.Fastest);
            using (var entryStream = entry.Open())
            {
                attachment.InputStream.CopyTo(entryStream);
            }
        }
    }
    ...
}
21
Alex

完璧な答えを提供してくれた@Alexに感謝します。
シナリオでは、ファイルシステムから読み取る必要もあります。

using (var ms = new MemoryStream())
{
    using (var zipArchive = new ZipArchive(ms, ZipArchiveMode.Create, true))
    {
        foreach (var file in filesAddress)
        {
            zipArchive.CreateEntryFromFile(file, Path.GetFileName(file));
        }
    }

    ...
}

System.IO.Compression.ZipFileExtensionsの助けを借りて

0
Soren