System.IO.FileNotFoundException 的含义是啥 [重复]

Posted

技术标签:

【中文标题】System.IO.FileNotFoundException 的含义是啥 [重复]【英文标题】:What's the meaning of a System.IO.FileNotFoundException [duplicate]System.IO.FileNotFoundException 的含义是什么 [重复] 【发布时间】:2022-01-14 02:18:10 【问题描述】:

我在 C# 程序中有这段代码:

ListOfCabins();
ListOfWoodTypes();

第一个函数如下所示:

private void ListOfCabins()

    Logger.Info($"Start function ListOfCabins()");

    try
    
    
    catch (Exception ex)
    
         ...
    

    Logger.Info($"End of function ListOfCabins()");

另外一个函数如下:

private void ListOfWoodTypes()

    Logger.Info($"Start function ListOfWoodTypes()");
    ...

Logger 是一个典型的NLog 对象:

private static readonly Logger Logger = LogManager.GetCurrentClassLogger();

在日志中,我看到:

End of function ListOfCabins()

我没看到:

Start function ListOfWoodTypes()

我的应用程序崩溃了,我在事件日志中看到:

Application: ...
Framework Version: v4.0.30319
Description: The process wa terminated due to an unhandled exception.
Exception Info: System.IO.FileNotFoundException
  at ...ListOfWoodTypes()
  at ...

我在这里有不同的问题:

System.IO.FileNotFoundException,这是否意味着我的应用程序正常,尝试打开一些不存在的外部文件,或者它类似于 Java 进程,缺少 *.class 文件? 为什么System.IO.FileNotFoundException 没有被我的try ... catch (Exception ex) 子句捕获? 日志呢?我希望至少能看到ListOfWoodTypes() 函数的第一行。这是否意味着NLog 技术中有一些缓冲,导致NLog 日志记录在崩溃时有一些延迟?

Edit1,无法调试 我正在自己的 PC 上开发这个程序,我在这里构建它,但是我将可执行文件复制到我客户的 PC,因此无法调试。

重新打开请求 我的问题与“.NET Global exception handler in console application”无关,它是针对这一例外的。此外,正如我自己的回答所示,Windows 事件日志中并未完全处理此特定异常。

【问题讨论】:

Exception Info: System.IO.FileNotFoundException at ...ListOfWoodTypes() - 我猜你的... ListOfWoodTypes()-code 里面有问题。不过,我们不能说,因为你没有分享它。另外:您是否尝试过逐步执行该方法, 看看它到底在哪里中断? 表示没有找到文件。您的处理程序不会捕获异常,因为它没有发生在您的 try 块内(例如,在单独的线程上)。这些都是在没有上下文的情况下简单推断出来的。其余的则需要调试器。 当您可以在日志中看到End of function ListOfCabins() 时,您为什么希望catch 块起作用?这清楚地表明代码已经离开了 try/catch 块的范围。 附带说明:是的,Nlog 可能会做一些缓存,但绝不应该发生后面的消息可见而较早的消息不可见的情况。你的代码流有些奇怪。 不,在该示例中,显示的异常将是 TypeLoadException 并且 - 在应用程序日志中 - 内部异常将不可见。这是可能的异常层次结构顶层的 FileNotFoundException。 【参考方案1】:

让我开始 - 这并不像听起来那么容易。正如他们所说,魔鬼在细节中......

System.IO.FileNotFoundException

这通常意味着有人扔了它。时期。找不到文件是应该抛出的,但我看到愚蠢的程序员滥用系统异常,或者“找不到文件”有时被解释得非常复杂(可以使用文件 api 打开网络流)。因此,虽然这表明 - 你知道 - 未找到文件,但不能 100% 确定这是触发它的原因。

为什么我的 try ... catch 没有捕获到 System.IO.FileNotFoundException (Exception ex) 子句?

你告诉我们。它应该是 - 如果它被扔在里面。

您自己的代码前后都有记录器信息。并且日志记录可能会进入 - 你猜怎么着 - 一个文件。假设第一行可能会引发错误并不是完全超现实的。

我们不知道——你应该知道。当抛出此异常时,在调试器中进行中断。获取它被抛出的确切位置。查看调用堆栈。看看属性。异常通常包含额外的数据——消息,可能是属性。只是告诉我们细节就像“一辆梅赛德斯坠毁,错误是什么”。调试详细信息可能会回答您的所有问题。

日志呢?我希望至少看到第一行 ListOfWoodTypes() 函数。

是的,除非那行抛出异常。 如果没有日志文件,我强烈建议 - 你知道 - 日志记录是问题所在。

这是否意味着NLog技术中存在一些缓冲,导致NLog 日志记录对崩溃有一些延迟?

嗯,该技术正在“使用标准 .NET 缓存”……不使用它是完全愚蠢的。看,问题是如果你不缓存,你需要大量的disci IO,这可能会使日志记录成为主要的性能消耗。你不能拥有这个。

但是:缓存与否,文件是否存在?如果不是 - 这就是你的暗示。文件生成不被缓存(写入是,但文件必须在那里才能打开流)。文件不存在...

【讨论】:

因此,基本上,您的声明是:“将日志添加到崩溃的应用程序是定位崩溃源的好方法。但是,如果您通过在已经存在的@之外添加这些日志来做到这一点987654321@ 子句,您最终可能会创建一个新的(类型)崩溃。不要那样做!!!” :-) 谢谢你的好建议! 没有。不必要。在上面的示例中,应用程序 START (!) 可能已经被记录并且 - 这将触发崩溃。一旦结束,您就知道日志记录是有效的。我不会梦想在没有应用程序开始日志记录的情况下添加日志记录。它更像是“不要仅仅因为您将日志条目添加到所有方法而没有在启动期间测试日志是否有效,就假设您的日志记录有效。 你不会相信代码的结构:try Logger.Info(...) ... catch (Exception ex) Logger.Error(...);,所以如果因为Logger而引发异常,我只会继续落入同样的陷阱:-) 【参考方案2】:

System.IO.FileNotFoundException

这意味着文件存在问题。所以,你认为你的程序想要打开一个输入文件,或者一个输出文件,...,或者你的日志文件,这也可能是一个文件,导致了那个异常。

但还有另一种文件:DLLs!!!

会发生这种情况:我正在使用 NuGet 包。由于NuGet Restore 有问题,我决定直接参考DLL 文件,但由于我需要进行一些升级,所以升级也必须在目标环境中完成,我完全忘记了。 当应用程序崩溃时,存在是否调试应用程序的问题。按下那个按钮终于让我看到了丢失的文件。

只是一个很小的问题:显然,丢失的文件是已知的。 是否可以在事件日志中包含该文件的名称?我想这对很多人来说可能非常有用!

【讨论】:

以上是关于System.IO.FileNotFoundException 的含义是啥 [重复]的主要内容,如果未能解决你的问题,请参考以下文章