Для работы с каталогами в пространстве имен System.IO предназначены сразу два класса: Directory и DirectoryInfo.
Статический класс Directory предоставляет ряд методов для управления каталогами. Некоторые из этих методов:
CreateDirectory(path): создает каталог по указанному пути path
Delete(path): удаляет каталог по указанному пути path
Exists(path): определяет, существует ли каталог по указанному пути path. Если существует, возвращается true
,
если не существует, то false
GetCurrentDirectory(): получает путь к текущей папке
GetDirectories(path): получает список подкаталогов в каталоге path
GetFiles(path): получает список файлов в каталоге path
GetFileSystemEntries(path): получает список подкаталогов и файлов в каталоге path
Move(sourceDirName, destDirName): перемещает каталог
GetParent(path): получение родительского каталога
GetLastWriteTime(path): возвращает время последнего изменения каталога
GetLastAccessTime(path): возвращает время последнего обращения к каталогу
GetCreationTime(path): возвращает время создания каталога
Данный класс предоставляет функциональность для создания, удаления, перемещения и других операций с каталогами. Во многом он похож на Directory, но не является статическим.
Для создания объекта класса DirectoryInfo применяется конструктор, который в качестве параметра принимает путь к каталогу:
public DirectoryInfo (string path);
Основные методы класса DirectoryInfo:
Create(): создает каталог
CreateSubdirectory(path): создает подкаталог по указанному пути path
Delete(): удаляет каталог
GetDirectories(): получает список подкаталогов папки в виде массива DirectoryInfo
GetFiles(): получает список файлов в папке в виде массива FileInfo
MoveTo(destDirName): перемещает каталог
Основные свойства класса DirectoryInfo:
CreationTime: представляет время создания каталога
LastAccessTime: представляет время последнего доступа к каталогу
LastWriteTime: представляет время последнего изменения каталога
Exists: определяет, существует ли каталог
Parent: получение родительского каталога
Root: получение корневого каталога
Name: имя каталога
FullName: полный путь к каталогу
Как видно из функционала, оба класса предоставляют похожие возможности. Когда же и что использовать? Если надо совершить одну-две операции с одним каталогом, то проще использовать класс Directory. Если необходимо выполнить последовательность операций с одним и тем же каталогом, то лучше воспользоваться классом DirectoryInfo. Почему? Дело в том, что методы класса Directory выполняют дополнительные проверки безопасности. А для класса DirectoryInfo такие проверки не всегда обязательны.
Посмотрим на примерах применение этих классов
string dirName = "C:\\"; // если папка существует if (Directory.Exists(dirName)) { Console.WriteLine("Подкаталоги:"); string[] dirs = Directory.GetDirectories(dirName); foreach (string s in dirs) { Console.WriteLine(s); } Console.WriteLine(); Console.WriteLine("Файлы:"); string[] files = Directory.GetFiles(dirName); foreach (string s in files) { Console.WriteLine(s); } }
Обратите внимание на использование слешей в именах файлов. Либо мы используем двойной слеш: "C:\\"
, либо одинарный,
но тогда перед всем путем ставим знак @: @"C:\Program Files"
Аналогичный пример с DirectoryInfo:
string dirName = "C:\"; var directory = new DirectoryInfo(dirName); if (directory.Exists) { Console.WriteLine("Подкаталоги:"); DirectoryInfo[] dirs = directory.GetDirectories(); foreach (DirectoryInfo dir in dirs) { Console.WriteLine(dir.FullName); } Console.WriteLine(); Console.WriteLine("Файлы:"); FileInfo[] files = directory.GetFiles(); foreach (FileInfo file in files) { Console.WriteLine(file.FullName); } }
Методы получения папок и файлов позволяют выполнять фильтрацию. В качестве фильтра в эти методы передается шаблон, который может содержать два плейсхолдера: * или символ-звездочка (соответствует любому количеству символов) и ? или вопросительный знак (соответствует одному символу)
Например, найдем все папки, которые начинаются на "books":
// класс Directory string[] dirs = Directory.GetDirectories(dirName, "books*."); // класс DirectoryInfo var directory = new DirectoryInfo(dirName); DirectoryInfo[] dirs = directory.GetDirectories("books*.");
Или получим все файлы с расширением ".exe":
// класс Directory string[] files = Directory.GetFiles(dirName, "*.exe"); // класс DirectoryInfo var directory = new DirectoryInfo(dirName); FileInfo[] files = directory.GetFiles("*.exe");
Класс DirectoryInfo
string path = @"C:\SomeDir"; string subpath = @"program\avalon"; DirectoryInfo dirInfo = new DirectoryInfo(path); if (!dirInfo.Exists) { dirInfo.Create(); } dirInfo.CreateSubdirectory(subpath);
Вначале проверяем, существует ли создаваемый каталог, и если он не существует, то создаем его. В итоге у нас получится следующий путь: "C:\SomeDir\program\avalon"
Аналогичный пример с классом Directory:
string path = @"C:\SomeDir"; string subpath = @"program\avalon"; if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } Directory.CreateDirectory($"{path}/{subpath}");
string dirName = "C:\\Program Files"; DirectoryInfo dirInfo = new DirectoryInfo(dirName); Console.WriteLine($"Название каталога: {dirInfo.Name}"); Console.WriteLine($"Полное название каталога: {dirInfo.FullName}"); Console.WriteLine($"Время создания каталога: {dirInfo.CreationTime}"); Console.WriteLine($"Корневой каталог: {dirInfo.Root}");
Если мы просто применим метод Delete
к непустой папке, в которой есть какие-нибудь файлы или подкаталоги, то приложение
нам выбросит ошибку. Поэтому нам надо передать в метод Delete
дополнительный параметр булевого типа, который укажет, что папку
надо удалять со всем содержимым. Кроме того, перед удалением следует проверить наличие удаляемой папки, иначе приложение выбросит исключение:
string dirName = @"C:\SomeDir"; DirectoryInfo dirInfo = new DirectoryInfo(dirName); if (dirInfo.Exists) { dirInfo.Delete(true); Console.WriteLine("Каталог удален"); } else { Console.WriteLine("Каталог не существует"); }
Или так:
string dirName = @"C:\SomeDir"; if (Directory.Exists(dirName)) { Directory.Delete(dirName, true); Console.WriteLine("Каталог удален"); } else { Console.WriteLine("Каталог не существует"); }
При перемещении надо учитывать, что новый каталог, в который мы хотим перемесить все содержимое старого каталога, не должен существовать.
string oldPath = @"C:\SomeFolder"; string newPath = @"C:\SomeDir"; DirectoryInfo dirInfo = new DirectoryInfo(oldPath); if (dirInfo.Exists && !Directory.Exists(newPath)) { dirInfo.MoveTo(newPath); // или так // Directory.Move(oldPath, newPath); }
Перемещение каталога в рамках одной папки (как в примере выше) фактически аналогично переименованию папки