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

7 に答える 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()、またはその他の問題について心配する必要はありません。

于 2009-10-24T03:37:14.710 に答える
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は0から8までの9バイトの長さです。

しかし、0から9までのあなたの読書...

于 2009-08-31T07:49:32.653 に答える
1

私はあなたの電話はあなたの電話の前にFinishあるべきだと思います。Close

更新:これは既知のバグのようです。すでに修正されている可能性があります。SharpZipLibのバージョンをチェックして、修正が組み込まれているかどうかを確認する必要があります。そうでない場合は、すべてのファイルを新しいアーカイブにコピーし、新しいファイルを追加してから、新しいアーカイブを古いアーカイブ名に移動することで、この問題を回避できます。

于 2009-08-31T06:05:05.470 に答える
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();
    }
于 2010-11-29T08:30:15.030 に答える
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);
}

現在、アーカイブには2つのフォルダ 画像が含まれています----> img1.jpg、img2、.jpgと別のフォルダ ファイル-> customer.pdf、sample.doc

于 2012-07-27T13:03:48.990 に答える
0

クラスは既存のZipOutputStreamZIPファイルを更新しません。ZipFile代わりにクラスを使用してください。

于 2013-12-09T22:37:58.803 に答える
-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();
于 2012-06-24T12:43:10.107 に答える