Ошибка повреждения центрального каталога в ziparchive

В моем коде С# я пытаюсь создать zip-папку, которую пользователь может загрузить в браузере. Итак, идея здесь в том, что пользователь нажимает кнопку загрузки и получает zip-папку.

В целях тестирования я использую один файл и архивирую его, но когда это сработает, у меня будет несколько файлов.

Вот мой код

var outPutDirectory = AppDomain.CurrentDomain.BaseDirectory;
string logoimage = Path.Combine(outPutDirectory, "images\\error.png"); // I get the file to be zipped

HttpContext.Current.Response.Clear();
HttpContext.Current.Response.BufferOutput = false;
HttpContext.Current.Response.ContentType = "application/zip";
HttpContext.Current.Response.AddHeader("content-disposition", "attachment; filename=pauls_chapel_audio.zip");


using (MemoryStream ms = new MemoryStream())
     {
          // create new ZIP archive within prepared MemoryStream
          using (ZipArchive zip = new ZipArchive(ms))
             {
                    zip.CreateEntry(logoimage);
                    // add some files to ZIP archive

                    ms.WriteTo(HttpContext.Current.Response.OutputStream);
             }
     }

Когда я пытаюсь это сделать, это дает мне эту ошибку

Центральный каталог поврежден.

[System.IO.IOException] = {Была предпринята попытка переместить позицию перед началом потока.}

Исключение возникает в

используя (ZipArchive zip = новый ZipArchive (мс))

Есть предположения?


person mohsinali1317    schedule 13.11.2015    source источник
comment
Просто примечание, если вы пытаетесь разархивировать файлы: если zip находится в вашей папке OneDrive, OneDrive выключен, а файл находится в онлайн-режиме, вы получите ту же ошибку. Просто снова включите OneDrive, и он должен работать.   -  person Nicke Manarin    schedule 15.12.2019


Ответы (1)


Вы создаете ZipArchive без указания режима, что означает, что он сначала пытается прочитать из него, но читать нечего. Вы можете решить эту проблему, указав ZipArchiveMode.Create в вызове конструктора.

Другая проблема заключается в том, что вы записываете MemoryStream в вывод перед закрытием ZipArchive..., что означает, что код ZipArchive не имел возможности выполнить какую-либо хозяйственную работу. Вам нужно переместить часть записи после вложенного оператора using, но обратите внимание, что вам нужно изменить способ создания ZipArchive, чтобы оставить поток открытым:

using (MemoryStream ms = new MemoryStream())
{
    // Create new ZIP archive within prepared MemoryStream
    using (ZipArchive zip = new ZipArchive(ms, ZipArchiveMode.Create, true))
    {
        zip.CreateEntry(logoimage);
        // ...
    }        
    ms.WriteTo(HttpContext.Current.Response.OutputStream);
 }
person Jon Skeet    schedule 13.11.2015
comment
Все еще получаю ту же ошибку. Исключение возникает при использовании (ZipArchive zip = new ZipArchive(ms)) - person mohsinali1317; 13.11.2015
comment
@ChaudhryMohsinAli: Ах. Было бы лучше, если бы ты сказал это с самого начала. - person Jon Skeet; 13.11.2015
comment
Я только что узнал, где происходит ошибка. - person mohsinali1317; 13.11.2015
comment
@ChaudhryMohsinAli: урок, который нужно усвоить, состоит в том, чтобы всегда включать полную трассировку стека при публикации сообщения об ошибке. Я все еще расследую. - person Jon Skeet; 13.11.2015
comment
@ChaudhryMohsinAli: см. мою правку. Я протестировал этот код, и он работает нормально. - person Jon Skeet; 13.11.2015
comment
Теперь у меня другая ошибка, как кажется. Изображение, которое я использовал для теста, когда я открываю его после распаковки zip-папки, в нем ничего нет. Размер изображения 0 байт. - person mohsinali1317; 13.11.2015
comment
@ChaudhryMohsinAli: если это работает из ASP.NET, то, возможно, файл находится не там, где вы думаете ... вы можете сначала разрешить имя файла относительно веб-контекста. - person Jon Skeet; 13.11.2015
comment
какие-либо индикаторы того, как это сделать? - person mohsinali1317; 13.11.2015
comment
@ChaudhryMohsinAli: я не разработчик ASP.NET, но я считаю, что это зависит от того, какую версию вы используете и т. д. HttpServerUtility.MapPath - это один из способов, но сейчас могут быть лучшие подходы. - person Jon Skeet; 13.11.2015