JavaRush /Курсы /C# SELF /Экземплярные классы FileIn...

Экземплярные классы 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() или её фактического появления.

2
Задача
C# SELF, 39 уровень, 1 лекция
Недоступна
Вывод списка файлов в директории
Вывод списка файлов в директории
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ