今天,我想帮跟踪并修复一个非常常见且非常著名的异常:System.IO.FileNotFoundException。承认!在所有情况下,此错误都是由于尝试访问不存在的文件所致。但是,实际上有多种情况可以触发此异常。你可能认为你知道关于这个例外的一切,但我打赌你还有一些东西要学。至少我在深入了解这篇文章的细节时做到了。请继续关注以了解全部情况。
文件类型未找到错误
找不到文件“filename”
如消息所述,您正在尝试加载找不到的文件。可以使用一行代码复现此类错误:
try { File.ReadAllText("non-existing.file"); } catch (FileNotFoundException e) { Console.WriteLine(e.ToString()); }
第三行是这里最重要的一条。我正在尝试加载文件系统中不存在的文件(non existing.file)。在上面的示例中,程序将输出打印到控制台,如下所示:
System.IO.FileNotFoundException: Could not find file 'APP_PATHinDebug on-existing.file'. File name: 'APP_PATHinDebug on-existing.file' at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost) at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost) at System.IO.StreamReader..ctor(String path, Encoding encoding, Boolean detectEncodingFromByteOrderMarks, Int32 bufferSize, Boolean checkHost) at System.IO.File.InternalReadAllText(String path, Encoding encoding, Boolean checkHost) at System.IO.File.ReadAllText(String path) at ConsoleApp.Program.Main(String[] args) in APP_PATHProgram.cs:line 19
APP_PATH将是找不到的文件的绝对路径。这种类型的FileNotFoundException实际上包含调试问题所需的所有信息。异常消息包含一个很好的错误描述,以及丢失文件的绝对路径。如果要向用户显示路径,或者在找不到文件时创建该文件,则FileNotFoundException上有一个nifty属性可用:
catch (FileNotFoundException e) { File.Create(e.FileName); }
在本例中,我只是使用Filename属性创建丢失的文件。我已经看到代码解析异常消息以获取丢失文件的名称,当绝对路径在异常上可用时,这有点让人失望。
系统找不到指定的文件。(HRESULT的异常:0x80070002)
此错误通常在尝试加载不存在的程序集时引发。可以这样复现错误:
try { Assembly.LoadFile("c:\Nonexisting.dll"); } catch (FileNotFoundException e) { Console.WriteLine(e.ToString()); }
在这种情况下,程序仍然抛出一个FileNotFoundException。但异常消息不同:
System.IO.FileNotFoundException: The system cannot find the file specified. (Exception from HRESULT: 0x80070002) at System.Reflection.RuntimeAssembly.nLoadFile(String path, Evidence evidence) at System.Reflection.Assembly.LoadFile(String path) at ConsoleApp.Program.Main(String[] args) in APP_PATHProgram.cs:line 20
与读取丢失文件时引发的错误不同,来自System.Reflection命名空间的消息更难理解。若要查找此错误的原因,您需要查看堆栈跟踪,该跟踪提示这是在Assembly.LoadFile期间发生的。注意,异常消息中不存在文件名,在本例中,FileNotFoundException上的filename属性为空。
无法加载文件或程序集“assembly”或其依赖项之一。系统找不到指定的文件。
与上述错误类似的错误是无法加载文件或程序集“assembly”或其依赖项之一。系统找不到指定的文件。错误。这也意味着程序正在尝试加载找不到的程序集。可以通过创建使用其他程序集的程序来重新创建错误。生成程序,从binDebug文件夹中删除引用程序集(.dll文件),然后运行程序。在这种情况下,程序在启动时失败:
Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'Lib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified. at ConsoleApp.Program.Main(String[] args)
在本例中,我引用了一个名为Lib的程序集,它不存在于磁盘或全局程序集缓存(GAC)中。此错误的典型原因是引用的程序集不在文件系统上。这可能有多种原因。为了帮助您调试,需要检查以下几点:
- 如果要使用Azure DevOps或Octopus Deploy等系统进行部署,请确保将生成输出中的所有文件复制到目标。
- 在Visual Studio中的引用程序集上单击鼠标右键,单击“属性”,并确保“复制本地”设置为true:
在IIS上运行时出现访问错误
要确保应用程序池用户具有访问权限,请执行以下操作:
- 右键单击包含web应用程序的文件夹
- 单击属性
- 选择“安全”选项卡
- 单击编辑。。。
- 单击添加。。。
- 在文本区域中输入IIS AppPoolDefaultAppPool
- 单击“检查名称”并验证是否已解析用户
- 单击“确定”
- 将完全控制权分配给新用户并保存