[英]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.它说读取stream
的zip
然后将其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
放在ZipFile
的using
块周围会更有意义。 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.如果您只在ZipFile
的using
块之后处理它们,那么您 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
,这意味着ZipFile
的using
块在技术上可以放在else
中。 Also, the multiple-file logic never sets the resultValue
.此外,多文件逻辑从不设置resultValue
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.