Работа с файловой системой в C#: от основ до продвинутых техник
Работа с файловой системой — одна из ключевых задач при разработке приложений на C#. Будь то сохранение пользовательских данных, чтение конфигурационных файлов или обработка логов — умение эффективно взаимодействовать с файлами и директориями необходимо каждому .NET-разработчику. В этой статье мы разберём основные классы пространства имён System.IO, научимся создавать, читать и изменять файлы, а также рассмотрим лучшие практики обработки ошибок.
1. Основные классы для работы с файловой системой
В .NET для работы с файлами и директориями предусмотрено несколько ключевых классов. Рассмотрим их подробнее.
Класс File и FileInfo
File — статический класс, предоставляющий методы для создания, копирования, удаления и перемещения файлов. FileInfo — экземплярный класс, который позволяет работать с конкретным файлом.
using System.IO;
// Использование статического класса File
string path = @"C:\Temp\test.txt";
if (File.Exists(path))
{
string content = File.ReadAllText(path);
Console.WriteLine(content);
}
// Использование FileInfo
FileInfo fileInfo = new FileInfo(path);
if (fileInfo.Exists)
{
Console.WriteLine($"Размер файла: {fileInfo.Length} байт");
Console.WriteLine($"Дата создания: {fileInfo.CreationTime}");
}
Класс Directory и DirectoryInfo
Аналогично, Directory — статический класс для операций с директориями, а DirectoryInfo — для работы с конкретной папкой.
string dirPath = @"C:\Temp\MyFolder";
// Создание директории
Directory.CreateDirectory(dirPath);
// Получение информации о директории
DirectoryInfo dirInfo = new DirectoryInfo(dirPath);
if (dirInfo.Exists)
{
Console.WriteLine($"Поддиректории: {dirInfo.GetDirectories().Length}");
Console.WriteLine($"Файлы: {dirInfo.GetFiles().Length}");
}
Класс Path
Path — утилитарный класс для работы с путями. Он помогает комбинировать пути, извлекать расширения и имена файлов.
string fullPath = @"C:\Temp\myfile.txt";
string fileName = Path.GetFileName(fullPath); // myfile.txt
string extension = Path.GetExtension(fullPath); // .txt
string directory = Path.GetDirectoryName(fullPath); // C:\Temp
string combined = Path.Combine(@"C:\Temp", "newfile.txt"); // C:\Temp\newfile.txt
2. Чтение и запись файлов
В C# существует несколько способов чтения и записи файлов. Выбор зависит от размера данных и требуемой производительности.
Чтение текстовых файлов
Для небольших файлов удобно использовать однострочные методы:
// Чтение всего файла одной строкой
string text = File.ReadAllText("data.txt");
// Чтение всех строк в массив
string[] lines = File.ReadAllLines("data.txt");
// Чтение с помощью StreamReader (для больших файлов)
using (StreamReader reader = new StreamReader("largefile.txt"))
{
string line;
while ((line = reader.ReadLine()) != null)
{
Console.WriteLine(line);
}
}
Запись в файлы
// Запись строки
File.WriteAllText("output.txt", "Hello, World!");
// Запись массива строк
string[] lines = { "Первая строка", "Вторая строка" };
File.WriteAllLines("output.txt", lines);
// Дозапись в конец файла
File.AppendAllText("log.txt", $"{DateTime.Now}: Новая запись\n");
// Запись с помощью StreamWriter
using (StreamWriter writer = new StreamWriter("data.txt", append: true))
{
writer.WriteLine("Новая строка");
}
Работа с бинарными файлами
Для бинарных данных используйте FileStream и BinaryReader/BinaryWriter:
// Запись бинарных данных
using (BinaryWriter writer = new BinaryWriter(File.Open("data.bin", FileMode.Create)))
{
writer.Write(12345);
writer.Write(3.14);
writer.Write("Hello");
}
// Чтение бинарных данных
using (BinaryReader reader = new BinaryReader(File.Open("data.bin", FileMode.Open)))
{
int number = reader.ReadInt32();
double pi = reader.ReadDouble();
string text = reader.ReadString();
}
3. Управление директориями и файлами
Помимо чтения и записи, часто требуется выполнять операции по управлению файловой структурой.
Создание и удаление
string dirPath = @"C:\Temp\NewFolder";
string filePath = Path.Combine(dirPath, "example.txt");
// Создание директории (если не существует)
Directory.CreateDirectory(dirPath);
// Создание файла
File.Create(filePath).Close();
// Удаление файла
File.Delete(filePath);
// Удаление директории (рекурсивно)
Directory.Delete(dirPath, recursive: true);
Перемещение и копирование
string source = @"C:\Temp\source.txt";
string dest = @"C:\Temp\dest.txt";
// Копирование файла
File.Copy(source, dest, overwrite: true);
// Перемещение файла
File.Move(source, @"C:\Temp\moved.txt");
// Перемещение директории
Directory.Move(@"C:\Temp\OldDir", @"C:\Temp\NewDir");
Поиск файлов и директорий
string searchDir = @"C:\Projects";
// Поиск всех файлов .txt
string[] txtFiles = Directory.GetFiles(searchDir, "*.txt", SearchOption.AllDirectories);
// Поиск всех поддиректорий
string[] subDirs = Directory.GetDirectories(searchDir, "*", SearchOption.AllDirectories);
// Использование EnumerateFiles для больших директорий
foreach (string file in Directory.EnumerateFiles(searchDir, "*.*", SearchOption.AllDirectories))
{
Console.WriteLine(file);
}
4. Обработка исключений и лучшие практики
Работа с файловой системой всегда сопряжена с риском возникновения ошибок. Рассмотрим основные исключения и способы их обработки.
Типичные исключения
FileNotFoundException— файл не найденDirectoryNotFoundException— директория не найденаUnauthorizedAccessException— недостаточно прав доступаIOException— общая ошибка ввода-вывода (например, файл занят другим процессом)PathTooLongException— слишком длинный путь
Пример безопасной работы
try
{
string path = @"C:\