it-roy-ru.com

Как сжать несколько файлов в Zip-файле

Я пытаюсь сжать два текстовых файла в файл Zip. Вот как выглядит мой публичный метод:

public ActionResult Index()
{

    byte[] file1 = System.IO.File.ReadAllBytes(@"C:\file1.txt");
    byte[] file2 = System.IO.File.ReadAllBytes(@"C:\file2.txt");
    Dictionary<string, byte[]> fileList = new Dictionary<string, byte[]>();
    fileList.Add("file1.txt", file1);
    fileList.Add("file2.txt", file2);
    CompressToZip("Zip.zip", fileList);

    return View();
}

Вот как выглядит мой метод сжатия:

private void CompressToZip(string fileName, Dictionary<string, byte[]> fileList)
{
    using (var memoryStream = new MemoryStream())
    {
        foreach (var file in fileList)
        {
            using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
            {
                var demoFile = archive.CreateEntry(file.Key);

                using (var entryStream = demoFile.Open())
                using (var b = new BinaryWriter(entryStream))
                {
                    b.Write(file.Value);
                }
            }
        }

        using (var fileStream = new FileStream(fileName, FileMode.Create))
        {
            memoryStream.Seek(0, SeekOrigin.Begin);
            memoryStream.CopyTo(fileStream);
        }
    }

}

При таком подходе папка Zip отлично создается. Однако проблема в том, что я получаю только один файл в папке Zip (только второй файл будет создан внутри папки Zip) . Ошибок не найдено. 

Вопрос: Как сжать оба текстовых файла в папку Zip?

Заранее благодарю!

6
Dayan

Ваш код фактически сохраняет два отдельных архива Zip в файл Zip.zip (для каждого файла, который будет сжат), создается новая ZipArchive. Первый Zip-архив содержит только file1.txt, второй только file2.txt. Когда вы открываете Zip.zip в Windows Explorer, он показывает только содержимое второго архива Zip.

Чтобы создать один Zip-архив, содержащий оба файла, просто переместите создание ZipArchive за пределы цикла fileList:

using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
{
    foreach (var file in fileList)
    {                    
        var demoFile = archive.CreateEntry(file.Key);

        using (var entryStream = demoFile.Open())
        using (var b = new BinaryWriter(entryStream))
        {
            b.Write(file.Value);
        }
    }
}
10
Phil Ross

На первый взгляд, я бы предположил, что ваше утверждение foreach вокруг using var (archive = new ZipArchive...) неверно.

Таким образом, вы создаете новую ZipArchive каждый раз, когда выполняете цикл foreach.

Конечно, вы хотите создать ZipArchive и перебрать foreach внутри этого?

Как это:

private void CompressToZip(string fileName, Dictionary<string, byte[]> fileList)
{
    using (var memoryStream = new MemoryStream())
    {
        using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
        {
            foreach (var file in fileList)
            {   
                var demoFile = archive.CreateEntry(file.Key);

                using (var entryStream = demoFile.Open())
                using (var b = new BinaryWriter(entryStream))
                {
                    b.Write(file.Value);
                }
            }
        }

        using (var fileStream = new FileStream(fileName, FileMode.Create))
        {
            memoryStream.Seek(0, SeekOrigin.Begin);
            memoryStream.CopyTo(fileStream);
        }
    }
}

Надеюсь это поможет!

6
Geoff James
string startPath = @"c:\example\start";
string zipPath = @"c:\example\result.Zip";

ZipFile.CreateFromDirectory(startPath, zipPath);
0
user2629005