Очевидно, ZipArchive
хочет расширить или изменить размер потока архива ZIP.Однако вы предоставили MemoryStream
с фиксированной длиной потока (благодаря использованию конструктора MemoryStream(byte[], bool)
, который создает поток памяти с фиксированной длиной, равной длине массива, предоставленного дляконструктор).
Поскольку ZipArchive
хочет расширить (или изменить размер) потока, предоставьте изменяемый размер MemoryStream
(используя его конструктор без параметров).Затем скопируйте исходные данные файла в этот MemoryStream и продолжите манипуляции с ZIP-архивом.
И не забудьте сбросить MemoryStream позицию чтения / записи обратно в0
после копирования в него данных исходного файла, в противном случае ZipArchive будет видеть " End of Stream " только при попытке прочитать данные архива ZIP из этого потока.
using (var packageStream = new MemoryStream())
{
using (var fs = File.OpenRead(/* location of existing .zip */))
{
fs.CopyTo(packageStream);
}
packageStream.Position = 0;
using (var zipPackage = new ZipArchive(packageStream, ZipArchiveMode.Update))
{
... do your thing ...
}
return packageStream.ToArray();
}
Этот код содержит еще одно исправление.В исходном коде, о котором идет речь, return packageStream.ToArray();
был помещен в блок using
ZipArchive .Во время выполнения этой строки экземпляр ZipArchive , возможно, еще не записал все данные в MemoryStream , возможно, некоторые данные остались в некоторых внутренних буферах и / или, возможно, были отложенызапись некоторых структур данных ZIP.
Чтобы ZipArchive действительно полностью записал все необходимые данные в MemoryStream , здесь достаточно переместить return packageStream.ToArray();
за пределыпосле блока ZipArchive using
.В конце блока using
будет удален ZipArchive , что также обеспечит запись ZipArchive всех пока не записанных данных в поток.Таким образом, доступ к MemoryStream после удаления ZipArchive приведет к получению полных данных полностью обновленного ZIP-архива.
Примечание: делайте это только с небольшими файлами ZIP. MemoryStream , очевидно, будет использовать внутренние буферы данных (массивы) для хранения данных в MemoryStream .Однако packageStream.ToArray();
создаст копию данных в MemoryStream , поэтому в течение некоторого времени требования к памяти для этой подпрограммы будут чуть более чем вдвое превышать размер ZIP-архива.