JavaRush /Курсы /C# SELF /Статические классы File

Статические классы File и Directory

C# SELF
39 уровень , 0 лекция
Открыта

1. Введение

Работать напрямую с потоками (StreamReader, StreamWriter, FileStream) очень полезно, особенно когда нужно контролировать процесс чтения/записи на низком уровне: например, писать блоки «по чуть-чуть» или обрабатывать большие файлы частями.

Но в реальной жизни часто нужно просто узнать: «существует ли этот файл?», «скопировать файл с места на место», «удалить файл», «получить список всех .txt-файлов в папке», и так далее. Для подобных задач Microsoft создала два универсальных инструмента: статические классы File и Directory. Статические — значит, создавать экземпляр не нужно, сразу вызываете нужный метод по имени класса.

Жизненная аналогия

Если потоки — это вы с карандашом, который аккуратно пишет каждую букву на листе бумаги, то File и Directory — это ваш стол с ящиками: вы можете «моментально» открыть ящик (Directory), достать из него бумажку (File.ReadAllText), выкинуть бумажку (File.Delete) или даже вытащить целый ящик и отправить его в другой конец комнаты (Directory.Move). Простые задачи — простые методы.

2. Класс File: что это и для чего нужен

У класса File есть очень удобный набор статических методов для всех популярных операций с файлами.

Самые часто используемые методы

Метод Описание
File.Exists(path)
Проверяет, есть ли файл по пути
File.ReadAllText(path)
Читает весь файл как текст
File.ReadAllLines(path)
Читает все строки файла в массив
File.WriteAllText(path, text)
Перезаписывает файл, записывая текст
File.AppendAllText(path, text)
Дописывает текст в конец файла
File.Copy(source, destination)
Копирует файл
File.Delete(path)
Удаляет файл
File.Move(source, destination)
Перемещает или переименовывает файл
File.Open/Read/Write/Create
Открывает поток для сложных операций

Быстрый пример: проверяем файл и читаем его

string filePath = "data.txt";

if (File.Exists(filePath))
{
    string content = File.ReadAllText(filePath);
    Console.WriteLine("Содержимое файла:");
    Console.WriteLine(content);
}
else
{
    Console.WriteLine("Файл не найден!");
}

Видите? Никакого ручного управления потоками для простого случая!

3. Класс Directory: управляй папками без боли

Если File — про отдельные файлы, то Directory — про папки (директории).

Основные задачи

Метод Описание
Directory.Exists(path)
Проверяет, есть ли папка
Directory.CreateDirectory(path)
Создаёт папку (или путь со всеми промежуточными папками)
Directory.Delete(path)
Удаляет папку (можно с поддиректориями)
Directory.GetFiles(path)
Получает список файлов в папке
Directory.GetDirectories(path)
Получает список поддиректорий
Directory.Move(source, destination)
Перемещает или переименовывает папку
Directory.GetCurrentDirectory()
Получить текущую рабочую директорию приложения

Пример: создаём папку и сохраняем туда файл

string dirPath = "Results";
if (!Directory.Exists(dirPath))
{
    Directory.CreateDirectory(dirPath);
    Console.WriteLine("Папка 'Results' создана.");
}

string filePath = Path.Combine(dirPath, "summary.txt");
File.WriteAllText(filePath, "Итоговые данные: ...");

Console.WriteLine($"Файл {filePath} записан.");

4. Типичные сценарии использования File и Directory

Базовые методы покажутся скучными, если не видеть их в деле! Посмотрим, как можно использовать эти классы для решения реальных задач и, заодно, продолжим развитие нашего условного приложения (давайте представим, что мы делаем простую систему для ведения списка дел — todo-list, результат сохраняем в файлы).

Сохранение данных в файл (замена старого файла)

// Сохраняем список задач в файл
string[] todos = { "Купить хлеб", "Позвонить врачу", "Сделать домашку по C#" };
string filePath = "todo.txt";
File.WriteAllLines(filePath, todos);

Console.WriteLine("Список дел сохранён.");

Загрузка данных из файла

// Загружаем задачи, если файл есть
if (File.Exists(filePath))
{
    string[] loadedTodos = File.ReadAllLines(filePath);
    Console.WriteLine("Ваш список дел:");
    foreach (var task in loadedTodos)
    {
        Console.WriteLine("- " + task);
    }
}
else
{
    Console.WriteLine("У вас пока нет списка дел.");
}

Добавление новой задачи (без перезаписи файла)

string newTask = "Погулять с собакой";
File.AppendAllText(filePath, newTask + Environment.NewLine);
Console.WriteLine("Задача добавлена!");

Копирование и резервное копирование файла

string backupPath = "todo_backup.txt";
File.Copy(filePath, backupPath, overwrite: true);
Console.WriteLine("Резервная копия списка дел создана.");

Перемещение (или переименование) файла

string archivePath = "todo_archive.txt";
File.Move(filePath, archivePath);
Console.WriteLine("Список дел архивирован (переименован).");

Удаление файла

if (File.Exists(archivePath))
{
    File.Delete(archivePath);
    Console.WriteLine("Архив удалён — освобождаем место!");
}

5. Работа с папками: примеры

Создание иерархии директорий

string path = Path.Combine("Reports", "2024", "June");
Directory.CreateDirectory(path);
Console.WriteLine($"Папка {path} создана (включая промежуточные папки).");

Получение списка файлов и папок

string dirPath = "Reports";
if (Directory.Exists(dirPath))
{
    string[] files = Directory.GetFiles(dirPath);
    Console.WriteLine("Файлы в папке:");
    foreach (var file in files)
    {
        Console.WriteLine(file);
    }

    string[] subDirs = Directory.GetDirectories(dirPath);
    Console.WriteLine("Поддиректории:");
    foreach (var dir in subDirs)
    {
        Console.WriteLine(dir);
    }
}

Фильтрация файлов по маске (только txt)

string[] txtFiles = Directory.GetFiles(dirPath, "*.txt");
Console.WriteLine("Только .txt-файлы:");
foreach (var file in txtFiles)
{
    Console.WriteLine(file);
}

Рекурсивный обход (файлы во всех подкаталогах)

string[] allFiles = Directory.GetFiles(dirPath, "*.*", SearchOption.AllDirectories);
Console.WriteLine("Файлы во всех вложенных папках:");
foreach (var file in allFiles)
{
    Console.WriteLine(file);
}

Перемещение и удаление директорий

string from = "OldReports";
string to = "Archive/OldReports";
if (Directory.Exists(from))
{
    Directory.Move(from, to);
    Console.WriteLine($"Папка {from} перемещена в {to}");
}

if (Directory.Exists(to))
{
    Directory.Delete(to, recursive: true); // true: удалить всё внутри
    Console.WriteLine($"Папка {to} удалена (со всем содержимым).");
}

6. Полезные нюансы

Интеграция с путями: класс Path

При работе с файлами и папками часто приходится составлять полные пути, объединять имена директорий и файлов, разбирать расширения, проверять допустимость символов. Для этого используют вспомогательный класс Path.

Примеры

string folder = "Results";
string filename = "week1.txt";
string fullPath = Path.Combine(folder, filename); // безопасное объединение!
Console.WriteLine(fullPath); // "Results/week1.txt" (или "\" на Windows)
  • Получить расширение файла: Path.GetExtension(fullPath)
  • Получить имя файла без пути: Path.GetFileName(fullPath)

Используйте Path.Combine вместо конкатенации строк — это безопаснее для кроссплатформенных приложений.

Методы «всё и сразу» против потокового варианта

Многие методы File и Directory (например, File.ReadAllText, File.WriteAllText, Directory.GetFiles) делают всю работу «целиком»: считывают/записывают/получают список файлов за одну операцию. Это ОЧЕНЬ удобно, но не подходит для очень больших файлов или каталогов, где может закончиться память. Если работаете с гигабайтами — переходите на потоковые классы (StreamReader, StreamWriter, FileStream и т.д.) или обработку файлов по частям.

Когда использовать File/Directory, а когда — классы потоков

Ситуация Что использовать
Нужно проверить, есть ли файл/папка
File.Exists, Directory.Exists
Прочитать/записать весь небольшой файл
File.ReadAllText, WriteAllText
Добавить текст в конец файла
File.AppendAllText
Получить список файлов в директории
Directory.GetFiles
Копировать, удалить, переместить файл
File.Copy/Delete/Move
Копировать/удалить целую папку Directory.Delete/Move/Copy (Copy — со сторонней библиотекой)
Обрабатывать ОЧЕНЬ большие файлы по частям Классы потоков (StreamReader, FileStream)

Практическое значение и реальное применение

  • Быстрая загрузка/сохранение конфигураций, настроек, JSON/XML-файлов.
  • Системы логирования (запись логов на диск).
  • Простые утилиты резервного копирования (бэкапы) и миграции данных.
  • Сканирование папок с мультимедиа, фотографиями, документами.
  • Пользовательские сценарии: загрузка шаблонов, экспорт/импорт, генерация отчётов и пр.

Практические задачи на собеседованиях тоже часто требуют использовать именно эти классы: «Реализуйте функцию, которая считает суммарный размер всех .txt файлов в директории», «Сделайте резервную копию файлов в отдельную папку» и т.п.

Визуальная шпаргалка: когда какой метод использовать

graph TD
    A[Что вы хотите сделать?]
    A -->|Проверить существование| B[File.Exists или Directory.Exists]
    A -->|Прочитать/записать файл целиком| C[File.ReadAllText/WriteAllText]
    A -->|Добавить данные в файл| D[File.AppendAllText]
    A -->|Работа с папками| E[Directory.CreateDirectory, GetFiles, GetDirectories]
    A -->|Копировать/удалить/переместить файл| F[File.Copy/Delete/Move]
    A -->|Копировать/удалить папку целиком| G[Directory.Delete/Move]

7. Особенности и типичные ошибки

Проверка на существование и «состояние гонки». Даже если проверить, что файл/папка существует, между этой проверкой и реальной операцией другой процесс может всё изменить. Поэтому всегда используйте try-catch даже если уже проверили наличие!

Права доступа. Если приложению не хватает прав на чтение/запись/удаление, методы выбросят UnauthorizedAccessException.

Путь слишком длинный. Максимальная длина пути (обычно 260 символов на старых Windows; в .NET 9 ограничения мягче, но всё равно остерегайтесь).

Ловля ошибок. Методы вроде File.ReadAllText или Directory.GetFiles не прощают ошибок: если файла/папки нет — сразу исключение. Оберните в try-catch либо предварительно проверьте наличие.

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