Как я должен использовать ZipArchive с потоками памяти?

Моя проблема в том, что как только ZipArchive удаляется, он автоматически закрывается и удаляет файл MemoryStream. Если я смотрю на поток до удаления ZipArchive, информация не правильно сформирована zip.

using (var compressStream = new MemoryStream())
{
    using (var zipArchive = new ZipArchive(compressStream, ZipArchiveMode.Create))
    {
        // Adding a couple of entries
        string navStackInfo = Navigation.NavState.CurrentStackInfoLines();
        var navStackEntry = zipArchive.CreateEntry("NavStack.txt", CompressionLevel.NoCompression);
        using (StreamWriter writer = new StreamWriter(navStackEntry.Open()))
        {
             writer.Write(navStackInfo);
        }
        var debugInfoEntry = zipArchive.CreateEntry("CallStack.txt", CompressionLevel.Optimal);
        using (StreamWriter writer = new StreamWriter(debugInfoEntry.Open()))
        {
            // debugInfo.Details is a string too
            writer.Write(debugInfo.Details);
        }
        // ...
        // compressStream here is not well formed
    }
    // compressStream here is closed and disposed
}

Итак, как это должно работать? Может, единственная проблема в том, что он плохо сформирован? Я вижу номер заголовка "PK" внутри файла (а не только в начале) в начале каждой части записи. Я не уверен, хорошо это или нет. Конечно, если я сохраняю поток в файл, я не могу открыть его как zip-файл, что-то не так. (Однако в окончательном коде я не хочу материализовать файл в коде обработки сбоев.)


person Csaba Toth    schedule 12.02.2014    source источник
comment
Похоже, у вас есть лишняя скобка после write.Write(navStackInfo); который закрывает zipArchive.   -  person DavidN    schedule 12.02.2014
comment
@DavidN Спасибо, это было только что, потому что в моем реальном коде есть дополнительные проверки нулевого указателя и прочее, поэтому я упростил этот пример.   -  person Csaba Toth    schedule 13.02.2014
comment
Кстати, если я скажу using (var zipArchive = ZipFile.Open(@"wtf.zip", ZipArchiveMode.Create), результирующий физический zip-файл будет хорошо сформирован и значительно больше (50 КБ против 10 КБ), чем то, что я вижу в версии Stream. Таким образом, либо материал не сбрасывается из ZipArchive в поток, и/или поток не сбрасывается. Я пытался сбросить поток, но это не помогло.   -  person Csaba Toth    schedule 13.02.2014
comment
Возможно, следует рассматривать дубликат stackoverflow.com/q/12347775/1178314, который, кроме того, в настоящее время имеет более приемлемый ответ.   -  person Frédéric    schedule 15.05.2015
comment
Я также изменил правильный ответ здесь, чтобы оставить открытым.   -  person Csaba Toth    schedule 15.05.2015


Ответы (1)


Я только что столкнулся с той же проблемой и заметил, что для конструктора ZipArchive есть необязательный параметр с именем leaveOpen. В документации сказано: True to leave the stream open after the System.IO.Compression.ZipArchive object is disposed; otherwise, false.

Это решило проблему для меня.

person Jeremy    schedule 02.03.2015
comment
Хорошо знать. Я предполагаю, что это что-то новое, или мы все проглядели это. В области ZipArchive велась разработка. Спасибо за то, что дали нам знать. - person Csaba Toth; 03.03.2015
comment
Теперь, когда .NET находится на GitHub, я попытался найти его, но пока безуспешно github.com /dotnet/coreclr/search?q=ziparchive github.com/dotnet/ corefx/search?q=ziparchive - person Csaba Toth; 03.03.2015
comment
Ссылка на документ о перегрузке конструктора в msdn: msdn. microsoft.com/en-us/library/hh137431(v=vs.110).aspx - person Frédéric; 15.05.2015