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

C#-当找不到文件时,System.IO.File.GetLastAccessTime为什么返回预期值?,c#,exception,error-handling,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(""); 如果path参数中描述的文件不存在,则此方法返回1601年1月1日午夜12:00(C.E.)协调世界时(UTC),调整为本地时间 在第二种情况下,抛出参数异常 为什么在第一种情况下不会抛出File

请解释一下你的想法

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

  • 在第二种情况下,抛出参数异常


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

    我相信这是故意的


    午夜12:00,1601年1月1日(C.E)是MIN日期值,有些人认为它是无价值的,但在可空类型

    < P>我们处理两种不同的事情。 当使用无效参数调用方法时,它应该引发异常

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

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

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

    好吧,我没有编写任何
    System.IO
    库,所以我不能说我知道在什么时候抛出了什么异常。符合例外条件的内容将始终由开发人员决定

    不过,我可以尝试一下这背后的原因

    在许多情况下,拥有一个不存在的文件可能是预期的行为。只需点击文件系统来查询文件是否存在,然后再次点击以获取该文件的访问时间,与只需点击一次文件系统并验证结果相比,这似乎是一种开销。如果
    DateTime
    可为空,则可能会产生
    null
    ,正如人们可以想象的那样,
    IndexOf
    将产生
    -1

    然而,在第二种情况下,传递一个无效路径证明代码中的某个地方,某个地方对某个不可能工作的东西产生了期望,通过抛出一个异常来引起开发人员的注意可能是有道理的。

    如果你问这个问题上次访问文件“There\u no\u such\u file.txt”是什么时候?您可以回答“There\u no\u such\u file.txt”或“never”


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

    这是有文档记录的行为。从MSDN库主题的备注部分:

    如果path参数中描述的文件不存在,则此方法返回1601年1月1日午夜12:00(C.E.)协调世界时(UTC),调整为本地时间

    传递空字符串时出现的异常是由检查传递的字符串是否为有效路径名的代码生成的。公平地说,这可能是程序中的错误

    代码是显式的,因此它不是由于疏忽或错误而执行的。它使用FindFirstFile()API函数来定位文件。如果失败,它将检查Windows错误。并显式忽略“未找到文件”、“未找到路径”和“忙驱动器”错误

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

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


    总之,打开文件使其可靠。

    是的,但问题是为什么?很有趣。我想知道是否有人能想到该名称空间中使用相同模式的任何其他方法。问得好。我怀疑除了“这是设计的;你得问问微软“尽管…@David Neale:至少
    文件。如果找不到文件,Delete
    不会引发异常。”。删除尤其有趣,因为在Delete中找不到文件是一种非常罕见的情况,在这种情况下,方法无法完成它被告知要做的任何工作,但它仍然可以确信结果正是开发人员想要的。@David Hedlund:File.Delete的观点很好。尽管如此,至少要检查路径是否正确。正如您所说,由于最终结果是相同的,这似乎更符合逻辑。这是一个关于错误处理的一般性问题,我只是使用System.IO.File.GetLastAccessTime作为示例。与带负值的Math.Sqrt相同-没有例外,返回double.NaN。在调用GetLastAccessTime之前,我自然会检查文件是否存在。David Neale说:“这种行为看起来很奇怪。”假设您有一个解决方案,其中一个非存在文件是预期的行为,但是如果有一个文件,您想知道它的访问时间-并且您希望这是线程安全的。你必须反驳才能抓住!如果我们可以假设“这个文件存在并在文艺复兴晚期被访问”的说法是毫无意义的,那么这就是一种提供信息的方式。。。。正如