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
- Luôn try-catch cho I/O (file, network, DB). Không tin tưởng
File.Exists(race condition, permission). - Catch cụ thể trước, chung sau:
FileNotFoundException→DirectoryNotFoundException→IOException→Exception. - Log chi tiết:
ex.FileName,ex.Message,ex.StackTrace. - User-friendly message: Không show stack trace cho end-user.
- Retry policy cho transient errors (network share, antivirus lock): dùng
Pollylibrary.
Lưu ý
FileNotFoundExceptionkế thừa từIOException.DirectoryNotFoundExceptioncũng kế thừaIOException(khi đường dẫn thư mục sai).- .NET Core/.NET 5+ trên Linux: case-sensitive path.