ZetCode

C# FileNotFoundException

最后修改于 2025 年 4 月 20 日

本教程讲解如何在 C# 中使用 FileNotFoundException 类来处理缺失文件的情况。当尝试访问文件失败,因为文件不存在时,会抛出 FileNotFoundException。

FileNotFoundException 类表示当文件路径不存在时抛出的异常。它继承自 IOException 并提供有关缺失文件的附加信息。

FileNotFoundException 包括 FileName 和 FusionLog 等属性,有助于诊断问题。正确处理此异常对于 C# 应用程序中健壮的文件操作至关重要。

基本 FileNotFoundException 示例

此示例演示了尝试读取不存在的文件时如何捕获 FileNotFoundException。 try-catch 块优雅地处理异常。

Program.cs
using System;
using System.IO;

class Program
{
    static void Main()
    {
        try
        {
            string content = File.ReadAllText("nonexistent.txt");
            Console.WriteLine(content);
        }
        catch (FileNotFoundException ex)
        {
            Console.WriteLine("Error: The file was not found.");
            Console.WriteLine($"File name: {ex.FileName}");
            Console.WriteLine($"Message: {ex.Message}");
        }
    }
}

该代码尝试读取不存在的文件,从而触发异常。 catch 块捕获 FileNotFoundException 并显示错误详细信息。该示例展示了当指定文件不存在时,File.ReadAllText 如何抛出 FileNotFoundException

异常处理程序访问 FileName 属性以显示缺少哪个文件,并访问 Message 属性以获取错误描述。这种基本模式对于处理 C# 程序中的文件访问错误至关重要。

在访问之前检查文件是否存在

此示例展示了如何在尝试访问之前检查文件是否存在,以防止 FileNotFoundException。这是一种主动的错误处理方法。

Program.cs
using System;
using System.IO;

class Program
{
    static void Main()
    {
        string filePath = "data.txt";
        
        if (File.Exists(filePath))
        {
            string content = File.ReadAllText(filePath);
            Console.WriteLine(content);
        }
        else
        {
            Console.WriteLine($"File not found: {filePath}");
        }
    }
}

File.Exists 方法在尝试读取文件之前检查文件是否存在。 在许多情况下,这可以完全避免异常。 虽然此方法可以防止异常,但重要的是要注意,在检查和实际文件访问之间,文件可能会被删除或移动。

因此,对于关键操作,除了存在性检查之外,仍然应该使用异常处理。 此示例演示了 C# 中文件操作的防御性编程技术。

使用内部异常处理 FileNotFoundException

此示例演示了处理包含内部异常的 FileNotFoundException。 内部异常提供有关错误的附加上下文。

Program.cs
using System;
using System.IO;

class Program
{
    static void Main()
    {
        try
        {
            // Simulate a scenario that might throw with inner exception
            throw new FileNotFoundException("Config file not found", 
                new IOException("Disk error occurred"));
        }
        catch (FileNotFoundException ex)
        {
            Console.WriteLine($"File not found: {ex.FileName}");
            Console.WriteLine($"Message: {ex.Message}");
            
            if (ex.InnerException != null)
            {
                Console.WriteLine($"Inner exception: {ex.InnerException.Message}");
            }
        }
    }
}

该示例人为地创建了一个带有内部 IOException 的 FileNotFoundException 来演示该模式。 在实际应用程序中,当较低级别的文件操作失败时,可能会发生这种情况。 该代码展示了如何访问 FileNotFoundExceptionInnerException 属性。

此属性可以提供有关文件访问失败的根本原因的有价值的调试信息。 该示例说明了如何在处理与文件相关的异常时正确检查所有可用的错误信息。

带有自定义消息的 FileNotFoundException

此示例展示了如何抛出带有自定义错误消息的 FileNotFoundException。 自定义消息可以使用户更容易理解错误。

Program.cs
using System;
using System.IO;

class Program
{
    static void LoadConfiguration(string configPath)
    {
        if (!File.Exists(configPath))
        {
            throw new FileNotFoundException(
                $"The configuration file '{configPath}' was not found. " +
                "Please ensure the file exists and try again.", 
                configPath);
        }
        
        // Load configuration here
    }

    static void Main()
    {
        try
        {
            LoadConfiguration("appsettings.json");
        }
        catch (FileNotFoundException ex)
        {
            Console.WriteLine("Configuration Error:");
            Console.WriteLine(ex.Message);
        }
    }
}

当配置文件丢失时,LoadConfiguration 方法会抛出带有详细的用户友好消息的 FileNotFoundException。 该示例演示了如何构造一个带有自定义消息和文件名的 FileNotFoundException

与默认异常消息相比,此方法提供了更多的上下文,使用户更容易理解和解决问题。 自定义消息包括问题描述和建议的解决方案操作。

FileStream 操作中的 FileNotFoundException

此示例演示了在使用 FileStream 时处理 FileNotFoundException。 当以某些模式打开不存在的文件时,FileStream 会抛出此异常。

Program.cs
using System;
using System.IO;

class Program
{
    static void Main()
    {
        try
        {
            using (var fs = new FileStream("missing.dat", FileMode.Open))
            {
                // Work with the file stream
            }
        }
        catch (FileNotFoundException ex)
        {
            Console.WriteLine($"Failed to open file: {ex.FileName}");
            Console.WriteLine("Full path searched: " + 
                Path.GetFullPath(ex.FileName));
        }
    }
}

该代码尝试以 FileMode.Open 打开一个不存在的文件,这会触发异常。 处理程序显示了搜索的文件名和完整路径。 将 FileStreamFileMode.Open 结合使用时,如果文件不存在,构造函数会抛出 FileNotFoundException

该示例演示了如何通过将异常的 FileNamePath.GetFullPath 结合使用来获取搜索的完整路径。 这对于调试应用程序中的文件位置问题特别有用。

处理多个文件操作

此示例展示了如何在处理多个文件时处理 FileNotFoundException。 即使某些文件丢失,该代码也会继续处理。

Program.cs
using System;
using System.IO;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        List<string> files = new List<string> 
        { 
            "file1.txt", 
            "file2.txt", 
            "file3.txt" 
        };

        foreach (var file in files)
        {
            try
            {
                string content = File.ReadAllText(file);
                Console.WriteLine($"Content of {file}:");
                Console.WriteLine(content);
            }
            catch (FileNotFoundException)
            {
                Console.WriteLine($"Warning: {file} not found, skipping...");
            }
        }
    }
}

该程序处理文件列表,跳过任何丢失的文件,而不是完全失败。 此方法在循环内使用 try-catch 块来单独处理丢失的文件。 每次迭代都尝试读取一个文件,如果发生 FileNotFoundException,它会记录一个警告并继续处理下一个文件。

此模式适用于批处理场景,在这种场景中,即使发生单个文件访问失败,也应继续处理。 该示例展示了如何在 C# 中实现弹性文件处理逻辑。

高级 FileNotFoundException 处理

此示例演示了 FileNotFoundException 的高级处理,包括日志记录和恢复选项。 它展示了一种更复杂的错误处理方法。

Program.cs
using System;
using System.IO;

class Program
{
    static void ProcessFile(string filePath)
    {
        try
        {
            if (!File.Exists(filePath))
            {
                throw new FileNotFoundException(
                    "Required data file not found", 
                    filePath);
            }

            // Process the file
            Console.WriteLine($"Processing {filePath}...");
        }
        catch (FileNotFoundException ex)
        {
            LogError(ex);
            
            // Try fallback location
            string fallbackPath = Path.Combine(
                Environment.GetFolderPath(Environment.SpecialFolder.CommonDocuments),
                Path.GetFileName(filePath));
                
            if (File.Exists(fallbackPath))
            {
                Console.WriteLine($"Using fallback file: {fallbackPath}");
                ProcessFile(fallbackPath);
            }
            else
            {
                Console.WriteLine("No fallback available. Processing stopped.");
            }
        }
    }

    static void LogError(FileNotFoundException ex)
    {
        string logMessage = $"[{DateTime.Now}] File not found: {ex.FileName}\n" +
                           $"Message: {ex.Message}\n" +
                           $"Stack Trace: {ex.StackTrace}\n";
        
        File.AppendAllText("error.log", logMessage);
    }

    static void Main()
    {
        ProcessFile("important_data.dat");
    }
}

该示例包括错误日志记录,并尝试在放弃之前找到备用文件。 这代表了生产质量的错误处理。 ProcessFile 方法首先检查文件是否存在,如果文件丢失,则抛出 FileNotFoundException

catch 块使用 LogError 方法将错误详细信息记录到文件中,然后尝试在公共文档文件夹中查找该文件作为备用位置。 这演示了一种处理找不到文件的情况的综合方法,包括用于诊断的日志记录和备用恢复路径。

来源

FileNotFoundException 类文档

本教程介绍了在 C# 中使用 FileNotFoundException 处理缺失文件的情况,包括基本用法、预防技术和高级错误处理模式。

作者

我叫 Jan Bodnar,是一位充满热情的程序员,拥有丰富的编程经验。 我自 2007 年以来一直在撰写编程文章。 至今,我已撰写了超过 1,400 篇文章和 8 本电子书。 我拥有超过十年的编程教学经验。

列出所有 C# 教程