1. Вступ
Чому важливо перевіряти наявність файлу або каталогу?
Уявіть, що ви ведете щоденник, і у вашому застосунку передбачено додавання запису в кінець файлу. Усе йде чудово, доки файл існує. Але якщо файл випадково видалено, програма завершиться з помилкою, і всі ваші геніальні думки про сенс буття або, у крайньому разі, про погоду, щезнуть без сліду. Аналогічно, якщо ви хочете створити новий файл, щоб нічого не втратити, варто переконатися, що такого файлу ще немає.
У реальних застосунках — особливо в корпоративній та промисловій розробці — попередні перевірки наявності файлів і каталогів допомагають уникнути не лише помилок з боку користувача й критичних збоїв, а й заощадити команді чимало часу та зусиль і, що не менш важливо, позбавити зайвого головного болю.
Робота з файловою системою в .NET
У .NET для роботи з файлами та каталогами нам знадобляться такі базові класи (вони містяться у просторі імен System.IO):
- File — статичні методи для роботи з файлами: перевірки, копіювання, видалення тощо.
- Directory — статичні методи для роботи з каталогами.
Для перевірки наявності достатньо двох методів:
- File.Exists(path) — повертає true, якщо файл існує.
- Directory.Exists(path) — повертає true, якщо каталог існує.
2. Перевірка наявності файлу перед відкриттям
Приклад із життя
Припустімо, ви додали функцію відображення вмісту щоденника:
string diaryPath = "diary.txt";
if (File.Exists(diaryPath))
{
// Файл існує — читаємо й виводимо вміст.
using var reader = new StreamReader(diaryPath);
string content = reader.ReadToEnd();
Console.WriteLine("Ваш щоденник:\n" + content);
}
else
{
Console.WriteLine("Файл щоденника не знайдено!");
// Можна одразу створити новий файл, якщо потрібно
File.WriteAllText(diaryPath, "Це початок вашого щоденника.\n");
Console.WriteLine("Створено новий файл щоденника.");
}
У реальних проєктах такий підхід — обов’язковий: ви не покладаєтеся на «дива», а берете ситуацію під контроль.
3. Перевірка наявності файлу перед записом
Сценарій: застосунок створює звіти за розкладом. Треба, щоб кожен новий звіт не перезаписував попередній.
Для цього корисно перевірити, чи файл уже існує. Якщо так — можна, наприклад, попросити користувача ввести іншу назву або створити файл з унікальною назвою.
string reportPath = "report.txt";
if (File.Exists(reportPath))
{
Console.WriteLine($"Файл '{reportPath}' вже існує. Перейменуйте або видаліть старий файл.");
}
else
{
using var writer = new StreamWriter(reportPath);
writer.WriteLine("Це новий звіт за сьогодні!");
Console.WriteLine("Файл звіту успішно створено.");
}
Така перевірка врятує ваших користувачів (і вас теж!) від неприємних сюрпризів у вигляді перезаписаних файлів.
4. Перевірка наявності каталогу перед записом
Файли рідко лежать безпосередньо в корені проєкту. Їх зазвичай зберігають у спеціальних каталогах: logs/, reports/, data/ тощо. Перед записом файлу варто переконатися, що потрібний каталог існує.
string logsDir = "logs";
string logPath = Path.Combine(logsDir, "log.txt"); // Path.Combine допомагає безпечно зʼєднувати частини шляху
if (!Directory.Exists(logsDir))
{
Console.WriteLine("Каталог 'logs' не знайдено. Створюємо його...");
Directory.CreateDirectory(logsDir);
}
using var writer = new StreamWriter(logPath, append: true);
writer.WriteLine($"[{DateTime.Now}] Застосунок запущено.");
Console.WriteLine("Запис у файл журналу виконано успішно.");
До речі, метод Directory.CreateDirectory не згенерує виняток, якщо каталог уже існує, — він просто проігнорує виклик, тож попередню перевірку можна не виконувати, якщо вас влаштовує такий підхід.
5. Важливі нюанси
Особливості: відносні та абсолютні шляхи
Поширена помилка початківців: вони плутають відносні й абсолютні шляхи. Наприклад, якщо ви пишете File.Exists("data.txt"), програма шукатиме файл у поточному робочому каталозі. А де це? Це залежить від того, звідки запущено застосунок.
Для надійності використовуйте абсолютні шляхи або будуйте шлях за допомогою Path.Combine:
string myDocs = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
string filePath = Path.Combine(myDocs, "myapp", "settings.txt");
Шлях буде вказано явно, і ви не втратите файл з поля зору.
Важливі деталі перевірки
- Іноді перевірку виконують, а відразу після неї здійснюють повторні операції з тим самим обʼєктом файлу/каталогу. Між File.Exists і подальшим створенням чи видаленням може минути час, і інший процес може змінити стан. У критичних сценаріях додавайте обробку помилок через try-catch.
- Перевіряйте не лише наявність, а й права доступу. Іноді файл є, але в користувача немає прав доступу до нього.
- Для каталогів використовуйте Directory.Exists, не File.Exists — інакше завжди отримаєте false.
- Якщо шлях складається з кількох вкладених каталогів, наприклад "data/2024/04", то Directory.CreateDirectory("data/2024/04") створить увесь ланцюжок — це зручно й усуває потребу в зайвих перевірках.
А що буде, якщо не перевіряти?
Якщо ви спробуєте відкрити неіснуючий файл для читання — отримаєте FileNotFoundException. Якщо спробуєте створити файл у неіснуючому каталозі — DirectoryNotFoundException. Якщо програма працює під керуванням користувача, він побачить помилку й може роздратуватися. У виробничих системах це ризик втрат даних, грошей і часу. Тож «перевірка на наявність» — це не занудство, а ознака турботи про користувача (і про власний душевний спокій).
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ