C# - 为什么System.IO.File.GetLastAccessTime在找不到文件时返回预期值?

时间:2010-06-04 07:39:16

标签: c# exception error-handling

请解释一下你的想法。

1.  DateTime dt = System.IO.File.GetLastAccessTime("C:\\There_is_no_such_file.txt");
2.  DateTime dt = System.IO.File.GetLastAccessTime("");
  1. 如果路径参数中描述的文件不存在,则此方法返回公元1601年1月1日午夜12点(CE)协调世界时(UTC),并调整为当地时间。

  2. 在第二种情况下抛出参数异常。

  3. 为什么在第一种情况下不会抛出FileNotFoundException(或smth.simmilar)?

6 个答案:

答案 0 :(得分:11)

这是记录在案的行为。从MSDN Library主题中的“备注”部分:

如果路径参数中描述的文件不存在,则此方法返回午夜时间,即公元1601年1月1日午夜12点(CE)协调世界时(UTC),调整为当地时间。

传递空字符串时获得的异常是由检查传递的字符串是否为有效路径名的代码生成的异常。这是公平的,这将是该计划中的错误。

代码是明确的,因此不是由疏忽或错误完成的。它使用FindFirstFile()API函数来定位文件。如果失败,则检查Windows错误。并明确忽略,“未找到文件”,“未找到路径”和“驱动器忙”错误。

请注意提供使用File.Exists的解决方案实际上并不能解决此问题。 Windows是一种多任务操作系统。在Exists调用之后,您的线程可能会被抢占,而另一个进程可能会删除该文件。当你的线程重新获得CPU时,你仍然会得到假的日期。

获得准确日期的唯一保证方法是首先打开文件,这样任何人都无法删除您下面的文件。我认为这解释了为什么该方法的行为与它一样。框架设计师被困在岩石和坚硬的地方之间。如果他们首先打开文件,他们就有可能冒着其他程序轰炸文件共享错误的风险。如果他们不首先打开文件,他们就会冒着程序随机爆炸的风险。非常难以诊断。他们必须在两种不愉快的选择之间做出选择,他们选择了不会轰炸任何东西的选项。

Anyhoo,打开文件让它变得可靠。

答案 1 :(得分:2)

我们正在处理两件不同的事情。

当您使用无效参数调用方法时,它应该抛出异常。

如果文件不存在,则不一定是例外。因此,返回一个默认值,您可以测试并决定如何继续。对于GetLastAccessTime方法,文件存在并不重要。如果它对您的代码至关重要,那么您应该负责生成错误......

if (!File.Exists("C:\\There_is_no_such_file.txt")) {
    throw new FileNotFoundException();
}

答案 2 :(得分:1)

好吧,我没有写任何System.IO库,所以我不能声称​​回答到什么时候会抛出异常。什么是合格的例外将始终是开发人员的决定。

但是,我可以尝试一下这背后的推理。

在很多情况下,拥有不存在的文件可能是预期的行为。必须点击文件系统只是为了查询文件是否存在,然后再次点击它来获取该文件的访问时间,可能只是开销,而不是简单地点击文件系统一次并验证结果。如果DateTime可以为空,那么这可能会产生null,就像人们可以想象的那样IndexOf而不是-1

然而,在第二种情况下,传递无效路径证明代码中的某处,某些东西对于不可能工作的某些东西是一种期望,并且可能有理由将其带入引起开发人员的注意,通过抛出异常。

答案 3 :(得分:1)

如果您问“最后一次是什么时候,文件”There_is_no_such_file.txt“被访问了?”,您可以回答“没有这样的文件”或“从不”。

显然,设计IO库的团队选择了第二个答案,从未被表示为DateTime.MinValue

答案 4 :(得分:0)

我相信它的设计

1601年1月1日午夜12点,A.D。(C.E。)是最低日期值,有些人认为它是无价值,但那是在可空类型之后

答案 5 :(得分:0)

原因可能是您已关闭“调试”部分下的“启用非托管代码调试选项”项目属性。