JavaRush /Курси /C# SELF /Переміщення файлів і каталогів

Переміщення файлів і каталогів

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

1. Вступ

Сценаріїв, коли потрібні операції переміщення, — сила-силенна: перенесення «завантажених» файлів із тимчасового каталогу до каталогу документів, масове впорядкування фотографій, перейменування за шаблоном, розбір пошти та логів. Файлова система любить порядок — або принаймні його подобу. А хороший розробник має вміти цей порядок наводити.

До того ж ці завдання часто дають на співбесідах: «Напишіть утиліту, яка перейменує всі файли, додавши до них номер версії», або «Зробіть команду, що переміщує застарілі документи в архів». Розберімося, як це робиться у C#.

Огляд можливостей

У .NET є два основні способи переміщення й перейменування: використовувати статичні методи (File.Move, Directory.Move) або екземплярні методи (FileInfo.MoveTo, DirectoryInfo.MoveTo). Усі ці методи внутрішньо виконують ту саму операцію; відрізняється здебільшого синтаксис.

Як .NET «бачить» переміщення й перейменування?

Увага! Перейменування й переміщення — по суті одна операція: файл або каталог у файловій системі визначається своїм шляхом. Якщо шлях змінюється — вважається, що об’єкт «перемістився» або «перейменувався». Якщо ви змінюєте лише ім’я, лишаючи той самий каталог — це перейменування. Якщо змінюєте шлях цілком — це переміщення. Майже як у Шредінґера: об’єкт і переміщений, і перейменований, якщо вказати новий шлях із новим ім’ям!

2. Переміщення й перейменування файлів: приклади

Рухатимемося від простого до складного і продовжимо на базі нашого мініфайлового менеджера.

Статичний метод File.Move

Ось приклад, як перемістити (або перейменувати) файл:


// Переміщуємо файл test1.txt до іншого каталогу з новим іменем
File.Move(@"C:\Temp\test1.txt", @"C:\Archive\test1_archived.txt");

А якщо потрібно просто перейменувати файл у тому самому каталозі:


// Просто змінюємо ім’я файла
File.Move(@"C:\Temp\test1.txt", @"C:\Temp\test_renamed.txt");

Власне, це й усе. .NET просто змінює шлях об’єкта, якщо обидва шляхи доступні й немає конфліктів.

Статичний метод Directory.Move

З каталогами — аналогічно:


// Переміщуємо каталог
Directory.Move(@"C:\Temp\OldFolder", @"C:\Temp\NewFolder");

Можна як перейменувати каталог (нове ім’я в тому самому каталозі), так і перемістити його цілком в інше місце.

3. Екземплярні методи: FileInfo.MoveTo і DirectoryInfo.MoveTo

Коли у вас уже є об’єкт FileInfo або DirectoryInfo, можна викликати метод MoveTo():


var fileInfo = new FileInfo(@"C:\Temp\test1.txt");
fileInfo.MoveTo(@"C:\Archive\test1_archived.txt");

// Каталоги:
var dirInfo = new DirectoryInfo(@"C:\Temp\OldFolder");
dirInfo.MoveTo(@"C:\Temp\NewFolder");

Тут так само: якщо новий шлях — це той самий каталог, але з іншим ім’ям, відбувається перейменування; якщо інший каталог — переміщення.

4. А що, якщо файл уже існує в місці призначення?

Саме тут з’являються нюанси, що часто виявляються у найневідповідніший момент.

File.Move

Якщо за вказаним шляхом призначення файл уже існує — буде згенеровано виняток IOException, і програма завершиться з помилкою:


try
{
    File.Move("data.txt", "archive\\data.txt");
}
catch (IOException ex)
{
    Console.WriteLine("Файл призначення вже існує! " + ex.Message);
}

FileInfo.MoveTo

Ситуація така сама — IOException, якщо файл призначення вже є.

Directory.Move

З каталогами вимоги ще суворіші: якщо цільовий каталог уже існує — виняток. Не можна перемістити каталог у каталог, який уже зайнятий.

Висновок: завжди перевіряйте, чи немає такого файла або каталогу там, куди ви намагаєтеся записати!


// Спокійно перевіряємо, чи є файл за цільовим шляхом
if (!File.Exists("archive\\data.txt"))
{
    File.Move("data.txt", "archive\\data.txt");
}
else
{
    Console.WriteLine("Файл призначення вже існує!");
}

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

Приклад перейменування каталогу


var oldDir = @"C:\Projects\OldReport";
var newDir = @"C:\Projects\NewReport";

// Перевіряємо, чи немає нового каталогу і чи є старий
if (Directory.Exists(oldDir) && !Directory.Exists(newDir))
{
    Directory.Move(oldDir, newDir);
    Console.WriteLine("Каталог успішно перейменовано.");
}
else
{
    Console.WriteLine("Помилка: вихідний каталог не знайдено або новий уже існує.");
}

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

Увесь вміст каталогу (підкаталоги, файли) переміститься разом із ним без будь-яких додаткових команд. Це зручно: однією командою каталог з будь-якою вкладеністю опиняється в новому місці.

Найкращі практики та корисні методи класу Path

Коли перейменовуєте або переміщуєте файли, використовуйте методи з класу System.IO.Path, щоб коректно зібрати новий шлях або змінити ім’я файла:

  • Отримати ім’я файла без розширення: Path.GetFileNameWithoutExtension(path)
  • Замінити лише розширення: Path.ChangeExtension(path, ".bak")
  • Побудувати новий шлях з іншим ім’ям: Path.Combine(Path.GetDirectoryName(path), "newname.txt")

string oldPath = @"C:\Reports\2023_Final.docx";
string newName = "2023_Archive.docx";
string newPath = Path.Combine(Path.GetDirectoryName(oldPath)!, newName);

File.Move(oldPath, newPath);

6. Важливі нюанси та типові помилки

Права доступу та блокування

Якщо у вас немає прав на запис за одним із шляхів — буде згенеровано виняток UnauthorizedAccessException. Аналогічно, якщо файл використовується іншим процесом (наприклад, відкритий у Word), отримаєте помилку. Це дуже поширений випадок.

Переміщення між різними дисками і томами

По суті, File.Move реалізує швидку операцію перейменування всередині одного тому/диска. Якщо спробуєте перемістити файл з диска C на диск D — .NET автоматично виконає копіювання з подальшим видаленням вихідного файла. Якщо щось піде не так (наприклад, диск призначення заповнений), вихідний файл залишиться на місці.

Цікавий факт: майже всі сучасні файлові системи підтримують «швидке перейменування/переміщення» всередині тому, а під час переміщення між томами — копіювання + видалення.

Переміщення цілих каталогів (Directory.Move)

Не можна перемістити каталог усередину самого себе або у вкладений у нього каталог (наприклад, C:\Data у C:\Data\Archive) — це спричинить помилку.

Як безпечно переміщати?

Перед будь-яким переміщенням, особливо масовим, перевіряйте існування джерела (File.Exists, Directory.Exists) і відсутність конфлікту в місці призначення. І не забувайте про try-catch: файлова система непередбачувана й може видати помилку в найнесподіваніший момент.

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