c# sharpziplib добавление файла в существующий архив
Я пытаюсь добавить файл в существующий архив, используя следующий код. При запуске не отображаются ошибки или исключения,но и файлы не добавляются в архив. Есть идеи, почему?
using (FileStream fileStream = File.Open(archivePath, FileMode.Open, FileAccess.ReadWrite))
using (ZipOutputStream zipToWrite = new ZipOutputStream(fileStream))
{
zipToWrite.SetLevel(9);
using (FileStream newFileStream = File.OpenRead(sourceFiles[0]))
{
byte[] byteBuffer = new byte[newFileStream.Length - 1];
newFileStream.Read(byteBuffer, 0, byteBuffer.Length);
ZipEntry entry = new ZipEntry(sourceFiles[0]);
zipToWrite.PutNextEntry(entry);
zipToWrite.Write(byteBuffer, 0, byteBuffer.Length);
zipToWrite.CloseEntry();
zipToWrite.Close();
zipToWrite.Finish();
}
}
7 ответов:
ВDotNetZip добавление файлов в существующий zip действительно просто и надежно.
using (var zip = ZipFile.Read(nameOfExistingZip)) { zip.CompressionLevel = Ionic.Zlib.CompressionLevel.BestCompression; zip.AddFile(additionalFileToAdd); zip.Save(); }
Если вы хотите указать путь к каталогу для этого нового файла, то используйте другую перегрузку для AddFile ().
using (var zip = ZipFile.Read(nameOfExistingZip)) { zip.CompressionLevel = Ionic.Zlib.CompressionLevel.BestCompression; zip.AddFile(additionalFileToAdd, "directory\\For\\The\\Added\\File"); zip.Save(); }
Если вы хотите добавить набор файлов, используйте AddFiles ().
using (var zip = ZipFile.Read(nameOfExistingZip)) { zip.CompressionLevel = Ionic.Zlib.CompressionLevel.BestCompression; zip.AddFiles(listOfFilesToAdd, "directory\\For\\The\\Added\\Files"); zip.Save(); }
Вам не нужно беспокоиться о Close(), CloseEntry(), CommitUpdate(), Finish() или любой другой дряни.
Из Codeproject кто-то использовал этот код. Единственная разница-закрыть и закончить otherway вокруг и написать часть:
using (ZipOutputStream s = new ZipOutputStream(File.Create(txtSaveTo.Text + "\\" + sZipFileName + ".zip"))) { s.SetLevel(9); // 0-9, 9 being the highest compression byte[] buffer = new byte[4096]; foreach (string file in filenames) { ZipEntry entry = new ZipEntry(Path.GetFileName(file)); entry.DateTime = DateTime.Now; s.PutNextEntry(entry); using (FileStream fs = File.OpenRead(file)) { int sourceBytes; do { sourceBytes = fs.Read(buffer, 0, buffer.Length); s.Write(buffer, 0, sourceBytes); } while (sourceBytes > 0); } } s.Finish(); s.Close(); }
Кстати:
byte[] byteBuffer = new byte[newFileStream.Length - 1]; newFileStream.Read(byteBuffer, 0, byteBuffer.Length);
Это неверно, размер-newFileStream.длина иначе чтение идет не так. У вас есть массив, и вы делаете его, например, 10-1 имеет длину 9 байт, от 0 до 8.
Но ваше чтение от 0 до 9...
Я думаю, что ваш
Finish
вызов должен быть Перед вашимClose
вызовом.Update: это выглядит какизвестная ошибка . Возможно, он уже был исправлен - вам нужно будет проверить версию SharpZipLib, чтобы увидеть, включает ли она какое-либо исправление. Если нет, вы можете обойти его, скопировав все файлы в новый архив, добавив новый файл, а затем переместив новый архив на старое имя архива.
/// <summary> /// 添加压缩文件 p 为客户端传回来的文件/夹列表,用分号隔开,不包括主路径, zipfile压缩包的名称 /// </summary> /// <param name="p"></param> /// <param name="zipfile"></param> public void AddZipFile(string p, string zipfile) { if (ServerDir.LastIndexOf(@"\") != ServerDir.Length - 1) { ServerDir += @"\"; } string[] tmp = p.Split(new char[] { ';' }); //分离文件列表 if (zipfile != "") //压缩包名称不为空 { string zipfilepath=ServerDir + zipfile; if (_ZipOutputStream == null) { _ZipOutputStream = new ZipOutputStream(File.Create(zipfilepath)); } for (int i = 0; i < tmp.Length; i++) { if (tmp[i] != "") //分离出来的文件名不为空 { this.AddZipEntry(tmp[i], _ZipOutputStream, out _ZipOutputStream); //向压缩文件流加入内容 } } } } private static ZipOutputStream _ZipOutputStream; public void Close() { _ZipOutputStream.Finish(); _ZipOutputStream.Close(); }
В корневом каталоге сайта есть папка ZippedFolder, внутри которой находится архив MyZipFiles.
Есть папка с именем siteImages, которая состоит из всех файлов изображений. Ниже приведен код для архивации изображений
string zipPath = Server.MapPath("~/ZippedFolder/MyZipFiles.zip"); using (ZipFile zip = new ZipFile()) { zip.AddFile(Server.MapPath("~/siteImages/img1.jpg"),string.Empty); zip.AddFile(Server.MapPath("~/siteImages/img2.jpg"),string.Empty); zip.AddFile(Server.MapPath("~/siteImages/img2.jpg"),string.Empty); zip.Save(zipPath); }
Если у нас разные форматы файлов и мы хотим,чтобы ваши файлы были сохранены в соответствующих папках, вы можете указать код следующим образом.
string zipPath = Server.MapPath("~/ZippedFolder/MyZipFiles.zip"); using (ZipFile zip = new ZipFile()) { zip.AddFile(Server.MapPath("~/siteimages/img1.jpg"), "images"); zip.AddFile(Server.MapPath("~/siteimages/img2.jpg"), "images"); zip.AddFile(Server.MapPath("~/documents/customer.pdf"), "files"); zip.AddFile(Server.MapPath("~/documents/sample.doc"), "files"); zip.Save(zipPath); }
Теперь архив содержит две папки изображения ---- > img1.формат jpg , img2,.формат jpg и еще одна папка файлы -- > клиент.pdf, образец.doc
Я нашел простое решение, сохранив его только для ZipFile и ZipEntry
ZipFile zipExisting = ZipFile.Read(Server.MapPath("/_Layouts/includes/Template.zip")); ICollection<ZipEntry> entries = _zipFileNew.Entries; foreach (ZipEntry zipfile in entries) { zipExisting.AddEntry(zipfile.FileName, zipfile.InputStream); } zipExisting.Save(Response.OutputStream); Response.End();