答案可能与上下文有关,或者这可能不是正确的地方,因此,如果https://softwareengineering.stackexchange.com/是更合适的网站,请与我们联系。
我们正在重新处理应用程序中的所有文件I / O,以便编程到接口而不是现有的紧密耦合的System.IO实现。在调用File.Exists()
之前,当前代码有很多File.Delete()
个检查。我们有机会将File.Exists()
检查放在处理System.IO的实现中,并从消费代码中删除它们,所以类似
private IFileSystem fileSystem;
void methodName()
{
string filePath = "c:\\file.txt";
if (fileSystem.Exists(filePath)
fileSystem.Delete(filePath);
}
可能只会变成:
private IFileSystem fileSystem;
void methodName()
{
string filePath = "c:\\file.txt";
fileSystem.Delete(filePath);
}
问题是,如果文件不存在,fileSystem.Delete()是否应该抛出异常?我们无法想到我们域的一个很好的理由,但是当我们习惯于以某种方式运行的框架API时,不抛出异常似乎很奇怪。我们不是一个拥有不同语言和平台的超级经验丰富的人群,因此我们没有太多可以与之进行比较。
从代码消费者的角度来看,只是删除文件并且不必每次都检查,这将是很好的。这似乎是一场胜利。但这种思路是否有任何已知的危险?
编辑*
我应该补充一点,操作的重点是允许我们与Azure BLOB存储进行通信,其中API是不同的。因此,在System.IO中保持接近.NET约定并不重要。
答案 0 :(得分:3)
File.Delete()抛出的原因很多,特别是当您尝试删除C:\目录中的文件时。但不,不是因为它不存在。
非常重要的是要理解它为什么会这样运作。从你的代码片段看起来,你过分依赖File.Exists()就犯了一个巨大的错误。这对多任务操作系统来说是一个非常弱的保证。所有你知道的是,文件在Exists()运行的那一刻确实存在/不存在。它之后绝对没有关于文件状态的说法。另一个进程可能会在一微秒后删除或创建文件。通过不需要检查,您可以安全地删除文件而不会导致程序崩溃。
请注意,File.Exists()在许多其他情况下也是邪恶的。就像只检查它存在后打开文件一样。由于同样的原因,它无法可靠地工作,另一个进程当然可以在检查和尝试打开它之间删除文件。唯一可以确定的方法是打开而不用检查。如果它不存在那么异常会告诉你它。
如果这听起来很像线程竞赛的问题那么你就是对的,这就是它的确切含义。但通常没有办法使用像 lock 这样的语句来确保另一个进程不会搞砸你。您可以使用命名的Mutex来仲裁对文件的访问。典型的问题是,您必须处理一个不了解bean的过程。
答案 1 :(得分:0)
调用者可能想知道文件是否存在。以状态枚举或布尔值返回此信息。例外是意外错误甚至是使用错误。这是一个完全预期的案例。
我认为.NET文件系统API经常出错。它们不会传递Win32提供的所有信息。通常,如果不解析异常文本,您甚至无法找出发生了什么错误。
答案 2 :(得分:0)
为什么要吞下潜在的重要信息? 如果删除抛出UnauthorizedAccessException,因为该程序是在不同凭据下运行的,那该怎么办? 如果文件有阻止删除的锁定怎么办? 不要假设意想不到的事情不会发生。