Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> C#

Xử lý ngoại lệ FileNotFoundException trong C#

FileNotFoundException ném ra khi cố gắng truy cập file không tồn tại. Đây là exception checked (cần xử lý hoặc khai báo throw) trong nhiều API I/O.

Ví dụ gây lỗi

using System;
using System.IO;

class Program
{
    static void Main()
    {
        // File "new.txt" không tồn tại
        using (StreamReader sr = new StreamReader("new.txt"))
        {
            string content = sr.ReadToEnd(); // Ném FileNotFoundException
        }
    }
}

Cách 1: Try-catch (Khuyến nghị cho I/O)

using System;
using System.IO;

class Program
{
    static void Main()
    {
        string path = "new.txt";
        
        try
        {
            using (StreamReader sr = new StreamReader(path))
            {
                string content = sr.ReadToEnd();
                Console.WriteLine("Nội dung: " + content);
            }
        }
        catch (FileNotFoundException ex)
        {
            Console.WriteLine($"File không tìm thấy: {ex.FileName}");
            Console.WriteLine($"Chi tiết: {ex.Message}");
        }
        catch (DirectoryNotFoundException ex)
        {
            Console.WriteLine($"Thư mục không tồn tại: {ex.Message}");
        }
        catch (IOException ex) // Base class của FileNotFoundException
        {
            Console.WriteLine($"Lỗi I/O khác: {ex.Message}");
        }
        catch (UnauthorizedAccessException ex)
        {
            Console.WriteLine($"Không có quyền truy cập: {ex.Message}");
        }
    }
}

Cách 2: Kiểm tra trước (File.Exists) - Có race condition

string path = "new.txt";

if (File.Exists(path))
{
    using (var sr = new StreamReader(path))
        Console.WriteLine(sr.ReadToEnd());
}
else
{
    Console.WriteLine("File không tồn tại");
}
// CẢNH BÁO: Race condition - file có thể bị xóa giữa Exists() và Open()

Cách 3: File.Open với FileMode/OpenAccess/Share (Kiểm soát chi tiết)

using System;
using System.IO;

class Program
{
    static void Main()
    {
        try
        {
            // FileMode.Open: ném FileNotFoundException nếu không tồn tại
            // FileShare.Read: cho phép process khác đọc cùng lúc
            using (FileStream fs = File.Open("new.txt", FileMode.Open, FileAccess.Read, FileShare.Read))
            using (StreamReader sr = new StreamReader(fs))
            {
                Console.WriteLine(sr.ReadToEnd());
            }
        }
        catch (FileNotFoundException)
        {
            Console.WriteLine("File không tồn tại");
        }
    }
}

Best Practices

  1. Luôn try-catch cho I/O (file, network, DB). Không tin tưởng File.Exists (race condition, permission).
  2. Catch cụ thể trước, chung sau: FileNotFoundException → DirectoryNotFoundException → IOException → Exception.
  3. Log chi tiết: ex.FileName, ex.Message, ex.StackTrace.
  4. User-friendly message: Không show stack trace cho end-user.
  5. Retry policy cho transient errors (network share, antivirus lock): dùng Polly library.

Lưu ý

  • FileNotFoundException kế thừa từ IOException.
  • DirectoryNotFoundException cũng kế thừa IOException (khi đường dẫn thư mục sai).
  • .NET Core/.NET 5+ trên Linux: case-sensitive path.