就异常处理而言,删除文件最有效的方法是什么?
MSDN 告诉我们,当您调用“File.Delete( path );”时对于不存在的文件,会生成异常。
在删除之前调用删除方法并使用 try/catch 块来避免错误或验证文件是否存在会更有效吗?
我倾向于认为最好避免 try/catch 块。当您知道如何检查错误时,为什么还要让错误发生呢?
无论如何,这里有一些示例代码:
// Option 1: Just delete the file and ignore any exceptions
/// <summary>
/// Remove the files from the local server if the DeleteAfterTransfer flag has been set
/// </summary>
/// <param name="FilesToSend">a list of full file paths to be removed from the local server</param>
private void RemoveLocalFiles(List<string> LocalFiles)
{
// Ensure there is something to process
if (LocalFiles != null && LocalFiles.Count > 0 && m_DeleteAfterTransfer == true)
{
foreach (string file in LocalFiles)
{
try { File.Delete(file); }
catch { }
}
}
}
// Option 2: Check for the existence of the file before delting
private void RemoveLocalFiles(List<string> LocalFiles )
{
// Ensure there is something to process
if (LocalFiles != null && LocalFiles.Count > 0 && m_DeleteAfterTransfer == true)
{
foreach (string file in LocalFiles)
{
if( File.Exists( file ) == true)
File.Delete(file);
}
}
}
我想要实现的目标的一些背景: 该代码是 FTP 包装类的一部分,它将 FTP 功能的特性简化为仅需要的内容,并且可以通过单个方法调用进行调用。 在这种情况下,我们有一个名为“DeleteAfterTransfer”的标志,如果设置为 true 将完成这项工作。如果该文件一开始就不存在,我预计在到达这一点之前会出现异常。 我想我在这里回答了我自己的问题,但检查文件是否存在不如验证我是否有权执行该任务或任何其他潜在错误重要。
MSDN tells us that when you call "File.Delete( path );" on a file that doesn't exist an exception is generated.
Would it be more efficient to call the delete method and use a try/catch block to avoid the error or validate the existence of the file before doing the delete?
I'm inclined to think it's better to avoid the try/catch block. Why let an error occur when you know how to check for it.
Anyway, here is some sample code:
// Option 1: Just delete the file and ignore any exceptions
/// <summary>
/// Remove the files from the local server if the DeleteAfterTransfer flag has been set
/// </summary>
/// <param name="FilesToSend">a list of full file paths to be removed from the local server</param>
private void RemoveLocalFiles(List<string> LocalFiles)
{
// Ensure there is something to process
if (LocalFiles != null && LocalFiles.Count > 0 && m_DeleteAfterTransfer == true)
{
foreach (string file in LocalFiles)
{
try { File.Delete(file); }
catch { }
}
}
}
// Option 2: Check for the existence of the file before delting
private void RemoveLocalFiles(List<string> LocalFiles )
{
// Ensure there is something to process
if (LocalFiles != null && LocalFiles.Count > 0 && m_DeleteAfterTransfer == true)
{
foreach (string file in LocalFiles)
{
if( File.Exists( file ) == true)
File.Delete(file);
}
}
}
Some Background to what I'm trying to achieve:
The code is part of an FTP wrapper class which will simplify the features of FTP functionality to only what is required and can be called by a single method call.
In This case, we have a flag called "DeleteAfterTransfer" and if set to true will do the job. If the file didn't exists in the first place, I'd expect to have had an exception before getting to this point.
I think I'm answering my own question here but checking the existence of the file is less important than validating I have permissions to perform the task or any of the other potential errors.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
考虑到
File.Delete
不会引发异常:使用 File.Exists,这需要额外的到磁盘的往返每次(归功于 Alexandre C),加上 File.Delete 到磁盘的往返。这很慢。但是,如果您想在文件不存在时执行特定操作,这是唯一的方法。
使用异常处理。考虑到输入 try/catch 块相对较快< /a> (大约 4-6 m-ops,我相信),开销可以忽略不计,并且您可以选择捕获特定的异常,例如文件正在使用时的 IOException 。这可能非常有益,但是当文件不存在时您将无法执行操作,因为这不会抛出异常。 注意:这是避免竞争条件的最简单方法,正如 Alexandre C 在下面更详细地解释的那样。
同时使用异常处理和
File.Exists< /代码>。这可能是最慢的,但只是稍微慢一点,并且是捕获异常和在文件不存在时执行特定操作(发出警告?)的唯一方法。
我原来的答案的总结,给出了一些关于使用和处理异常的更一般的建议:
Exception
的 COM 异常时)。You have essentially three options, considering that
File.Delete
does not throw an exception when your file isn't there:Use File.Exists, which requires an extra roundtrip to the disk each time (credits to Alexandre C), plus a roundtrip to the disk for File.Delete. This is slow. But if you want to do something specific when the file doesn't exist, this is the only way.
Use exception handling. Considering that entering a try/catch block is relatively fast (about 4-6 m-ops, I believe), the overhead is negligible and you have the option to catch the specific exceptions, like
IOException
when the file is in use. This can be very beneficial, but you will not be able to act when the file does not exist, because that doesn't throw. Note: this is the easiest way to avoid race conditions, as Alexandre C explains below in more detail.Use both exception handling and
File.Exists
. This is potentially slowest, but only marginally so and the only way to both catch exceptions and do something specific (issue a warning?) when the file doesn't exist.A summary of my original answer, giving some more general advice on using and handling exceptions:
Exception
).另一种选择:使用 Windows API DeleteFile...
如果完成则返回 true,否则返回 false。如果为 false,则不会有异常的大量开销。
Another option: use Windows API DeleteFile...
This returns true if done, otherwise false. If false, you don't have the large overhead of Exceptions.
MSDN< /a> 表示不会生成异常。 实际上,这种方式更好,因为存在竞争条件:在对
File.Exists
和File.Delete 文件可能已被删除或由另一个进程创建。
如果要抛出,您最好捕获可能抛出的特定异常(
FileNotFoundException
或类似)。请注意,由于竞争条件,异常是到达这里的唯一方法。如果您的问题是包含该文件的目录不存在,那么您可以这样做:
同样,之前不要检查目录是否存在,因为 1) 它很麻烦 2) 它有同样的竞争条件问题。 只有
File.Delete
保证检查和删除是原子执行的。无论如何,您永远不想捕获这里的每个异常,因为文件IO方法可能会因多种原因而失败(并且您当然不想消除磁盘故障!)
MSDN says that no exception is generated. Actually, it is better this way since you have a race condition: between calls to
File.Exists
andFile.Delete
the file could have been deleted or created by another process.If it were to throw, you are better catching the specific exception that could have been thrown (
FileNotFoundException
or similar). Note that because of the race condition, exceptions are the only way to go here.If your problem is that the directory containing the file doesn't exist, then you can do:
Again, don't check for the directory existence before, because 1) it is cumbersome 2) it has the same race condition problem. Only
File.Delete
guarantees that the check and the delete are atomically executed.Anyways you never want to catch every exception here since file IO methods can fail for a lot of reasons (and you surely don't want to silent a disk failure !)
尝试删除文件时可能会发生许多异常。请在此处查看所有这些内容。因此,最好按照您认为合适的方式抓住并处理它们。
There are many exceptions that can occur when trying to delete a file. Take a look here for all of them. So it's probably best to catch and deal with each of them as you see fit.
您应该使用 File.Exists,但无论如何都要处理异常。一般来说,文件有可能在两次调用之间被删除。处理异常仍然有一些开销,但首先检查文件是否存在会将抛出频率降低到几乎从不。对于发生上述情况的百万分之一的可能性,您仍然可能因未处理的异常而毁掉某人的工作。
You should use
File.Exists
, but handle the exception anyway. In general it may be possible for the file to be deleted in between the two calls. Handling the exception still has some overhead, but checking the file for existence first reduces the throw frequency to almost-never. For the one in a million chance that the above scenario occurs, you could still ruin someone's work with an unhandled exception.在一般情况下,在调用方法之前测试异常情况确实更好,因为异常不应该用于控制流。
但是,我们在这里处理文件系统,即使您在删除文件之前检查文件是否存在,其他东西也可能会在两次调用之间删除它。在这种情况下,
Delete()
仍然会抛出异常,即使您明确确保它不会抛出异常。因此,在这种特殊情况下,我无论如何都会准备好处理异常。
In the general case, it's indeed better to test for the exceptional case before calling the method, as exceptions should not be used for control flow.
However, we're dealing with the filesystem here, and even if you check that the file exists before deleting it, something else might remove it between your two calls. In that case,
Delete()
would still throw an exception even if you explicitly made sure it wouldn't.So, in that particular case, I would be prepared to handle the exception anyway.
我认为你不仅应该担心效率,还应该担心意图。问自己这样的问题:
显然,即使文件存在,
Delete
调用也可能会失败,因此仅添加该检查并不能保护您的代码免遭失败;你仍然需要捕获异常。问题更多的是要捕获和处理什么异常,以及哪些异常应该向上冒泡给调用者。I think you should not only worry about efficiency, but also intention. Ask yourself questions like
Obviously, the
Delete
call can fail even if the file exists, so only adding that check will not protect your code from failure; you still need to catch exception. The question is more about what exceptions to catch and handle, and which ones should bubble upwards to the caller.最好先执行
File.Exists
。异常有很大的开销。在效率方面,您的定义不是很清楚,但在性能和内存方面,请选择File.Exists
。另请参阅我之前在这个问题中关于使用异常控制程序流的答案:
示例“使用异常来控制流程”
如下,我欢迎任何人自己尝试一下。人们谈论硬盘驱动器的主轴速度和访问时间 - 这是非常无关紧要的,因为我们没有计时。 OP询问完成他的任务最有效的方法是什么。正如您在这里所看到的那样,它是使用
File.Exists
。这是可重复的。:实际记录的性能结果:try/catch 与 File.Exists 对于不存在的文件
文件数量(不存在):10,000
来源:http://pastebin.com/6KME40md
结果:
RemoveLocalFiles1(try/catch):119ms
RemoveLocalFiles2(File.Exists):106ms
It's far better to do
File.Exists
first. Exceptions have a large overhead. In terms of efficiency, your definition isn't very clear, but performance and memory-wise, go forFile.Exists
.See also my previous answer in this question about using Exceptions to control program flow:
Example of "using exceptions to control flow"
As below, I welcome anyone to try this themselves. People talking about spindle speed and access times for hard drives - that is massively irrelevant, because we are not timing that. The OP asked what the most performant way of achieving his task is. As you can see clear as day here, it's to use
File.Exists
. This is repeatable.:Actual recorded performance results: try/catch vs File.Exists for non-existent files
Number of files (non-existent): 10,000
Source: http://pastebin.com/6KME40md
Results:
RemoveLocalFiles1 (try/catch) : 119ms
RemoveLocalFiles2 (File.Exists) : 106ms