简体   繁体   English

如何在 Dotnetzip 中删除 zip 文件

[英]How do I remove a zip file in Dotnetzip

I am trying to delete a zip file in DotNetZip as it is like transaction (either do it full or not at all).我正在尝试删除DotNetZip中的zip文件,因为它就像transaction一样(要么完整,要么根本不)。

Currently, I have incremented my count twice, on purpose to break the app and see if it saves the zip .目前,我已经将count incremented了两次,目的是为了打破应用程序并查看它是否保存了zip

Well it does, it saves the zip with 2 files instead of 3 and as I said I want it to behave like a transaction .确实如此,它使用 2 个文件而不是 3 个文件保存zip ,正如我所说,我希望它表现得像一个transaction

  using (ZipFile zip = new ZipFile(outputdirectory))
        {
            var count = 0;

        //    string invoiceNumber = documents[count].GetElementsByTagName("InvoiceNumber")[count].InnerText + ".xml";

            if (documents.Count == 1)
            {
                string invoiceNumber = documents[0].GetElementsByTagName("InvoiceNumber")[0].InnerText + ".xml";
                XmlWriterSettings settings = new XmlWriterSettings();
                settings.Encoding = Encoding.GetEncoding("UTF-8");
                SaveFiles(documents[0], invoiceNumber, settings);
                resultValue = InvoiceResult.Success;
            }
            else
            { 
                foreach (var document in documents)
                {
                    try
                    {
                        string invoiceNumber = documents[count].GetElementsByTagName("InvoiceNumber")[0].InnerText + ".xml";

                    count++;

                        using (MemoryStream memoryStream = new MemoryStream())
                        {
                            document.Save(memoryStream);

                            memoryStream.Seek(0, SeekOrigin.Begin);

                            zip.AddEntry($"{invoiceNumber}.xml", memoryStream);

                                zip.Save();

                        }
                    }
                    catch (Exception)
                    {
                        var wrongZip = ZipFile.Read(outputdirectory);                        
                        wrongZip.Dispose();
                        resultValue = InvoiceResult.CannotCreateZipFile;
                   //     throw new IOException($"Zip file in path {outputdirectory} has already been created. Please delete file if you want to make a new one.");
                    }
                    count++;

                }
            }
        }

I have found this article on Stackoverflow .我在Stackoverflow上找到了这篇文章。

DotNetZip how to delete a file after extracting DotNetZip如何在解压后删除文件

It said read the stream of the zip and then Dispose of it.它说读取streamzip然后将其Dispose I have tried that but the zip file still exists.我已经尝试过了,但是zip文件仍然存在。

No errors, just does not delete the file.没有错误,只是不删除文件。

There is quite a lot of chaos in that code;该代码中有很多混乱。 the combination of a counter and a foreach , looped re-saving of the zipfile, unnecessary re-reading of an already-open zipfile...计数器和foreach的组合,循环重新保存压缩文件,不必要地重新读取已经打开的压缩文件......

Since you literally said that any error in the saving process should lead to a full abort, it makes a lot more sense to put the try-catch around the ZipFile 's using block.由于您确实说过保存过程中的任何错误都会导致完全中止,因此将try-catch放在ZipFileusing周围会更有意义。 One of the functions of a using block is to clean up the object even in case of an exception, after all.毕竟, using块的功能之一是清理 object,即使发生异常也是如此。

As for the looped re-saving, personally, I'd simply make an array of MemoryStream objects, and in each loop iteration, fill one in, link it into the ZipFile as file, and save the ZipFile only once, after the whole loop.至于循环重新保存,就个人而言,我只是制作一个MemoryStream对象数组,并在每次循环迭代中填写一个,将其链接到ZipFile作为文件,并在整个循环之后只保存一次ZipFile . You can then safely dispose the MemoryStream objects from the array.然后,您可以安全地从数组中MemoryStream对象。 This way, they all exist simultaneously at the moment you save the ZipFile .这样,它们在您保存ZipFile时同时存在。 And if you only dispose them after the ZipFile 's using block you are 100% sure the ZipFile object no longer needs them.如果您只在ZipFileusing块之后处理它们,那么您 100% 确定ZipFile object 不再需要它们。

If you do it this way, nothing will ever be written in case an error occurs, since it never gets to the zip.Save() line.如果您这样做,则在发生错误时不会写入任何内容,因为它永远不会到达zip.Save()行。 So there will be no need to delete anything, either.所以也不需要删除任何东西。

try
{
    Int32 docCount = documents.Count;
    MemoryStream[] streams = null;
    using (ZipFile zip = new ZipFile(outputdirectory))
    {
        if (docCount == 1)
        {
            string invoiceNumber = documents[0].GetElementsByTagName("InvoiceNumber")[0].InnerText + ".xml";
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Encoding = Encoding.GetEncoding("UTF-8");
            SaveFiles(documents[0], invoiceNumber, settings);
            resultValue = InvoiceResult.Success;
        }
        else
        {
            streams = new MemoryStream[docCount]
            // Since we need an index for both the documents and streams array,
            // use 'for' and not 'foreach'
            for (Int32 i = 0; i < docCount; ++i)
            {
                var doc = documents[i];
                string invoiceNumber = doc.GetElementsByTagName("InvoiceNumber")[0].InnerText + ".xml";
                MemoryStream str = new MemoryStream();
                // Store stream in array so you can dispose it later
                streams[i] = str;
                doc.Save(str);
                str.Seek(0, SeekOrigin.Begin);
                zip.AddEntry($"{invoiceNumber}.xml", str);
            }
            zip.Save();
        }
    }
    if (streams != null)
        for (Int32 i = 0; i < docCount; ++i)
            if (streams[i] != null)
                streams[i].Dispose();
}
catch (Exception)
{
    resultValue = InvoiceResult.CannotCreateZipFile;
}

There do seem to be some details missing from this, though.不过,这似乎确实缺少一些细节。 The 1-file logic doesn't seem to use the ZipFile at all, meaning the ZipFile 's using block can technically just be placed inside the else . 1-file 逻辑似乎根本不使用ZipFile ,这意味着ZipFileusing块在技术上可以放在else中。 Also, the multiple-file logic never sets the resultValue .此外,多文件逻辑从不设置resultValue

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM