C# SharpZipLib:将文件添加到现有归档文件

7

我正在尝试使用以下代码向现有的存档文件中添加一个文件。运行时没有显示任何错误或异常,但是也没有将任何文件添加到存档文件中。有什么想法吗?

        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个回答

15

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()或任何其他复杂的东西。


我开始讨厌SharpZipLib了,它太底层了,阅读文档也很困惑。 - The Muffin Man

2

有人在Codeproject上使用了这段代码。唯一的区别是关闭和完成的顺序相反,而且写入部分:

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.length,否则读取会出错。

你有一个数组,例如10-1是9个字节长的,从0到8。

但你却从0到9进行读取...


嗨PoweRoy,我已经完全使用了这段代码,但是没有错误,也没有文件 :( - Grant
我也尝试过这个: ZipFile zipFile = new ZipFile(archivePath); zipFile.BeginUpdate(); ZipEntry entry = new ZipEntry(fileName); zipFile.Add(fileName); zipFile.CommitUpdate();但是路径都不对。我需要设置相对路径。 - Grant

1

我认为你的Finish调用应该在Close调用之前。

更新:这看起来像一个已知的错误。可能已经被修复了 - 你需要检查你的SharpZipLib版本,看看它是否包含任何修复。如果没有,你可以通过将所有文件复制到一个新的存档中,添加新文件,然后将新存档移动到旧存档名称来解决它。


1
    /// <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();
    }

0

ZipOutputStream类不会更新现有的ZIP文件。请改用ZipFile类。


0

网站根目录下有一个名为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);
}

现在存档包含两个文件夹 images ---- > img1.jpg,img2.jpg 和另一个文件夹 files --> customer.pdf,sample.doc


-1

我已经找到了一个简单的解决方案,只涉及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();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接