JavaRush /Курси /C# SELF /Екземплярні класи FileInfo...

Екземплярні класи FileInfo й DirectoryInfo

C# SELF
Рівень 39 , Лекція 1
Відкрита

1. Вступ

Якщо статичні класи, такі як File і Directory, — це як універсальний швейцарський ніж: завжди під рукою, швидко розв’язують завдання, але без прив’язки до конкретного об’єкта, то FileInfo й DirectoryInfo — це вже персоналізований інструмент: він створюється для конкретного файлу або каталогу, «знає» про них чимало й дає змогу працювати зручніше та гнучкіше, особливо під час багаторазових операцій із тим самим об’єктом.

Екземплярні класи зберігають деталі про конкретний об’єкт файлової системи, причому після першого зчитування властивостей не завжди потрібно знову звертатися до файлової системи по інформацію (якщо лише дані не застаріли).

  • FileInfo — для роботи з конкретним файлом.
  • DirectoryInfo — для роботи з конкретним каталогом (папкою).

Вони містять властивості й методи, які дають змогу отримувати детальну інформацію (розмір, дату створення, розширення, доступні атрибути) і виконувати над файлом/каталогом різні дії: копіювати, видаляти, переміщувати тощо.

Як влаштовані FileInfo й DirectoryInfo

Обидва класи — нащадки спільного абстрактного класу FileSystemInfo, який дає змогу писати код, що працює з файлами й каталогами одночасно.


System.Object
   |
System.MarshalByRefObject
   |
System.IO.FileSystemInfo (абстрактний клас)
   |             |
  FileInfo    DirectoryInfo

Коли використовувати екземплярні класи?

  • Якщо потрібно багато інформації про один файл або каталог (розмір, дата модифікації, розширення, атрибути тощо), і ці дані використовуються не один раз.
  • Якщо ви хочете перебрати всі файли та підкаталоги в каталозі й працювати з кожним об’єктом як із «живим» екземпляром.
  • Для оптимізації, коли важливо уникати зайвих звернень до файлової системи (кешування інформації).
  • Для більш об’єктно-орієнтованого коду (резервні копії, медіатека, файловий менеджер тощо).

Як створити екземпляр FileInfo або DirectoryInfo

using System.IO;

// Створення об’єкта FileInfo для наявного (або й неіснуючого!) файлу:
var fileInfo = new FileInfo("notes.txt");

// Створення об’єкта DirectoryInfo для каталогу:
var dirInfo = new DirectoryInfo(@"C:\Projects");

// Можна використовувати відносні або абсолютні шляхи!

Важливий момент: створення об’єкта FileInfo або DirectoryInfo НЕ створює файл/каталог у файловій системі! Це лише опис (зв’язок за посиланням).

2. Робота з FileInfo

Розберімо основні властивості та методи цього класу. Ось шпаргалка:

Властивість/метод Що повертає? Приклад використання
Name
Імʼя файлу
fileInfo.Name
FullName
Повний шлях
fileInfo.FullName
Length
Розмір файлу в байтах
fileInfo.Length
Directory
Батьківський каталог (DirectoryInfo)
fileInfo.Directory.FullName
Exists
Файл існує?
fileInfo.Exists
Extension
Розширення файлу (.txt)
fileInfo.Extension
CreationTime
Дата створення
fileInfo.CreationTime
LastWriteTime
Дата останньої зміни
fileInfo.LastWriteTime
IsReadOnly
Лише для читання?
fileInfo.IsReadOnly
Методи
CopyTo()
Копіювати файл
fileInfo.CopyTo("copy.txt")
Delete()
Видалити файл
fileInfo.Delete()
MoveTo()
Перемістити файл
fileInfo.MoveTo("move.txt")
OpenRead()
Відкрити потік для читання
using var stream = fileInfo.OpenRead()
OpenWrite()
Відкрити потік для запису
using var stream = fileInfo.OpenWrite()

Приклад: інформація про файл

Додамо невеликий модуль, який отримує детальну інформацію про файл, використовуючи FileInfo.

Console.WriteLine("Введіть імʼя файлу:");
string fileName = Console.ReadLine();

var file = new FileInfo(fileName);
if (file.Exists)
{
    Console.WriteLine($"Імʼя файлу: {file.Name}");
    Console.WriteLine($"Шлях: {file.FullName}");
    Console.WriteLine($"Розмір: {file.Length} байт");
    Console.WriteLine($"Розширення: {file.Extension}");
    Console.WriteLine($"Дата створення: {file.CreationTime}");
    Console.WriteLine($"Остання зміна: {file.LastWriteTime}");

    // Додатково: показати батьківський каталог
    Console.WriteLine($"Батьківський каталог: {file.DirectoryName}");
}
else
{
    Console.WriteLine("Файл не знайдено.");
}

Зверніть увагу: ми не читаємо вміст файлу, а просто отримуємо метаінформацію.

Практика: копіювання та видалення файлу

// ... Усередині основного методу після успішного виводу відомостей про файл:
Console.WriteLine("Введіть шлях для копії файлу:");
string copyPath = Console.ReadLine();

try
{
    file.CopyTo(copyPath);
    Console.WriteLine($"Файл успішно скопійовано в {copyPath}");
}
catch (IOException ex)
{
    Console.WriteLine($"Не вдалося скопіювати файл: {ex.Message}");
}

// Тепер видалимо копію
Console.WriteLine("Видалити копію файлу? (y/n):");
if (Console.ReadLine().Trim().ToLower() == "y")
{
    var copyFile = new FileInfo(copyPath);
    if (copyFile.Exists)
    {
        copyFile.Delete();
        Console.WriteLine("Копію видалено.");
    }
}

3. Робота з DirectoryInfo

Погляньмо, що вміє DirectoryInfo:

Властивість/метод Що повертає? Приклад використання
Name
Імʼя каталогу
dirInfo.Name
FullName
Повний шлях
dirInfo.FullName
Parent
Батьківський каталог (DirectoryInfo)
dirInfo.Parent.FullName
Exists
Каталог існує?
dirInfo.Exists
CreationTime
Дата створення
dirInfo.CreationTime
LastWriteTime
Дата зміни
dirInfo.LastWriteTime
Методи
Create()
Створити каталог
dirInfo.Create()
Delete()
Видалити каталог
dirInfo.Delete()
GetFiles()
Масив файлів (масив FileInfo)
dirInfo.GetFiles()
GetDirectories()
Масив підкаталогів (масив DirectoryInfo)
dirInfo.GetDirectories()
EnumerateFiles()
Перебирання файлів (повертає IEnumerable<FileInfo>, відкладене виконання)
dirInfo.EnumerateFiles()
MoveTo()
Перемістити каталог
dirInfo.MoveTo("path")

Приклад: перебирання файлів і каталогів

Console.WriteLine("Введіть шлях до каталогу:");
string path = Console.ReadLine();

var dir = new DirectoryInfo(path);
if (!dir.Exists)
{
    Console.WriteLine("Каталог не знайдено!");
    return;
}

Console.WriteLine("\n--- Файли ---");
foreach (var file in dir.GetFiles())
{
    Console.WriteLine($"{file.Name} ({file.Length} байт)");
}

Console.WriteLine("\n--- Підкаталоги ---");
foreach (var subDir in dir.GetDirectories())
{
    Console.WriteLine(subDir.Name);
}

4. Корисні нюанси

Статичні методи проти екземплярних класів

Коли варто використовувати який підхід? Якщо ви робите швидку «одноразову» дію — наприклад, File.Exists(path) або File.ReadAllText(path), — статичні методи будуть найзручнішими. Вони простіші й трохи швидші завдяки мінімальним накладним витратам.

Якщо ж ви хочете отримати багато інформації про файл або каталог, виконувати над цим об’єктом повторні операції або просто пишете код в ООП-стилі, — краще використовувати екземпляри FileInfo й DirectoryInfo.

Цікаво, що обидва підходи «під капотом» використовують схожі низькорівневі системні виклики. Але екземплярні класи кешують деякі властивості (розмір, дати, атрибути), мінімізуючи кількість звернень до файлової системи — особливо під час перебирання великої кількості файлів.

Трохи про роботу з датою й часом

Властивості CreationTime, LastWriteTime, LastAccessTime повертають значення типу DateTime.

Console.WriteLine($"Файл створено: {file.CreationTime:yyyy-MM-dd HH:mm:ss}");
Console.WriteLine($"Остання зміна: {file.LastWriteTime:yyyy-MM-dd HH:mm:ss}");

Якщо файл або каталог було змінено на диску після того, як ви отримали об’єкт FileInfo або DirectoryInfo, кешована інформація може застаріти. Щоб оновити її, викличте file.Refresh().

Поради та практичні зауваження

  • Екземплярні класи зручні, коли ви будуєте обгортку над файловою системою: резервні копії, медіатека, індексатор.
  • Чудово працюють разом із LINQ: можна відфільтрувати за розміром, датою або розширенням і виконати операції над обраними об’єктами.
  • Для масових операцій краще EnumerateFiles() і EnumerateDirectories(), ніж GetFiles()/GetDirectories(), — ліниве перебирання заощаджує памʼять і пришвидшує старт обробки.

Порівняння статичного та екземплярного підходу

Статичні методи Екземплярні класи
Синтаксис
File.Delete(path)
new FileInfo(path).Delete()
Кешування Ні Так
Багато інформації Потрібно викликати багато методів Є в об’єкті
ООП-стиль Ні Так
Масові операції Незручно Зручно
Робота з потоками Є Є

Оновлення інформації та об’єктів

Об’єкти FileInfo/DirectoryInfo кешують значення після першого звернення до властивостей. Якщо об’єкт (файл або каталог) було змінено на диску після створення екземпляра, щоб оновити інформацію, викличте метод .Refresh().

var file = new FileInfo("notes.txt");
long oldSize = file.Length;

// У цей час хтось (або ви самі) змінює файл поза програмою

file.Refresh();
long newSize = file.Length;

Таке трапляється нечасто, але якщо ваша програма спостерігає за файловою системою — механізм важливий.

5. Типові помилки під час роботи з екземплярними класами

Омана: якщо створено об’єкт new FileInfo("file.txt"), то файл уже існує. Насправді це не так — файл з’являється тільки після явного запису або виклику Create().

Спроба отримати властивості файлу, якого не існує: деякі властивості повернуть значення за замовчуванням (наприклад, розмір 0), але спроба відкрити потік читання спричинить виняток.

Із каталогами — так само: створення DirectoryInfo не гарантує, що каталог є на диску до виклику Create() або його фактичної появи.

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ