ZetCode

C# FileNotFoundException

last modified April 20, 2025

This tutorial explains how to use the FileNotFoundException class in C# to handle missing file scenarios. FileNotFoundException is thrown when an attempt to access a file fails because the file doesn't exist.

The FileNotFoundException class represents an exception that is thrown when a file path doesn't exist. It inherits from IOException and provides additional information about the missing file.

FileNotFoundException includes properties like FileName and FusionLog that help diagnose the issue. Proper handling of this exception is crucial for robust file operations in C# applications.

Basic FileNotFoundException Example

This example demonstrates catching a FileNotFoundException when attempting to read a non-existent file. The try-catch block handles the exception gracefully.

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}");
        }
    }
}

The code attempts to read a file that doesn't exist, triggering the exception. The catch block captures the FileNotFoundException and displays error details. The example shows how File.ReadAllText throws a FileNotFoundException when the specified file doesn't exist.

The exception handler accesses the FileName property to show which file was missing and the Message property for the error description. This basic pattern is essential for handling file access errors in C# programs.

Checking File Existence Before Access

This example shows how to prevent FileNotFoundException by checking file existence before attempting access. This is a proactive approach to error handling.

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}");
        }
    }
}

The File.Exists method checks for file existence before attempting to read it. This avoids the exception entirely in many cases. While this approach prevents the exception, it's important to note that between the check and the actual file access, the file could be deleted or moved.

Therefore, for critical operations, exception handling should still be used in addition to existence checks. This example demonstrates defensive programming techniques for file operations in C#.

Handling FileNotFoundException with Inner Exception

This example demonstrates handling a FileNotFoundException that includes an inner exception. Inner exceptions provide additional context about the error.

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}");
            }
        }
    }
}

The example artificially creates a FileNotFoundException with an inner IOException to demonstrate the pattern. In real applications, this might occur when lower-level file operations fail. The code shows how to access the InnerException property of FileNotFoundException.

This property can provide valuable debugging information about the root cause of the file access failure. The example illustrates how to properly examine all available error information when handling file-related exceptions.

FileNotFoundException with Custom Message

This example shows how to throw a FileNotFoundException with a custom error message. Custom messages can make errors more understandable to users.

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);
        }
    }
}

The LoadConfiguration method throws a FileNotFoundException with a detailed, user-friendly message when the config file is missing. The example demonstrates how to construct a FileNotFoundException with both a custom message and the filename.

This approach provides more context than the default exception message, making it easier for users to understand and resolve the issue. The custom message includes both the problem description and suggested action for resolution.

FileNotFoundException in FileStream Operations

This example demonstrates handling FileNotFoundException when working with FileStream. FileStream throws this exception when opening non-existent files in certain modes.

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));
        }
    }
}

The code attempts to open a non-existent file with FileMode.Open, which triggers the exception. The handler shows both the filename and full path that was searched. When using FileStream with FileMode.Open, the constructor throws FileNotFoundException if the file doesn't exist.

The example demonstrates how to get the full path that was searched by combining the exception's FileName with Path.GetFullPath. This is particularly useful for debugging file location issues in applications.

Handling Multiple File Operations

This example shows how to handle FileNotFoundException when processing multiple files. The code continues processing even if some files are missing.

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...");
            }
        }
    }
}

The program processes a list of files, skipping any that are missing instead of failing entirely. This approach uses a try-catch block inside the loop to handle missing files individually. Each iteration attempts to read a file, and if FileNotFoundException occurs, it logs a warning and continues with the next file.

This pattern is useful for batch processing scenarios where processing should continue despite individual file access failures. The example shows how to implement resilient file processing logic in C#.

Advanced FileNotFoundException Handling

This example demonstrates advanced handling of FileNotFoundException with logging and recovery options. It shows a more sophisticated error handling approach.

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");
    }
}

The example includes error logging and attempts to locate a fallback file before giving up. This represents production-quality error handling. The ProcessFile method first checks for the file's existence and throws a FileNotFoundException if it's missing.

The catch block logs the error details to a file using the LogError method, then attempts to find the file in a common documents folder as a fallback location. This demonstrates a comprehensive approach to handling file not found scenarios, including logging for diagnostics and alternative recovery paths.

Source

FileNotFoundException Class Documentation

This tutorial covered handling missing file scenarios in C# with FileNotFoundException, including basic usage, prevention techniques, and advanced error handling patterns.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all C# tutorials.