1. Клас Path

Якщо ви хочете написати програму, що працює з файлами на диску, ви можете легко це зробити. У Java є дуже багато класів, які допомагають працювати з файлами та їхнім вмістом.

У ранніх версіях Java для роботи з файлами використовувалися такі класи, як File і FileInputStream. Але тепер клас File вважається застарілим, і використовувати його не рекомендується. Щоправда, його й досі можна побачити в коді, параметрах методів або конструкторах класів.

Ми розпочнемо вивчення роботи з файлами відразу з класу Path. Path — це клас, який прийшов на зміну File. Його використання безпечніше й ефективніше.

Клас Path

Клас Path — це, власне, не клас, а інтерфейс. Так було зроблено для того, щоб для кожної операційної чи файлової системи можна було створити свій клас-спадкоємець Path.

Windows моє свій стандартний формат шляху файлів, Linux — свій. До того ж у світі є ще багато операційних систем, і кожна має свої стандарти.

Тому в усіх методах для роботи з файлами вказано інтерфейс Path, але в дійсності використовуються його класи-спадкоємці: WindowsPath, UnixPath, ...

Створення об'єкта Path

Для створення об'єкта Path (насправді це буде об'єкт класу-спадкоємця WindowsPath), використовується така команда:

Path ім'я = Path.of(шлях);

де ім'я — це ім'я змінної типу Path, шлях — це шлях до файлу (або директорії) разом з ім'ям файлу (або директорії), а of — це статичний метод класу Path.

Метод of() використовується для створення об'єктів типу WindowsPath, якщо програма призначена для ОС Windows, або об'єктів UnixPath, якщо програма призначена для ОС Linux. Ви не можете створити об'єкт типу Path за допомогою коду new Path().

Приклади:

Код Примітка
Path file = Path.of("c:\\projects\\note.txt");
Шлях до файлу
Path directory = Path.of("c:\\projects\\");
Шлях до директорії

Для існування валідного об'єкта типу Path необов'язково має існувати файл (або директорія). Можливо, ви тільки збираєтеся створити цей файл… Об'єкт типу Path — це немов розширена версія типу String: він не прив'язаний до певного файлу на диску, а просто зберігає якийсь шлях.


2. Методи типу Path

Інтерфейс Path має чимало цікавих методів. Найцікавіші з них наведено в цій таблиці.

Метод Опис
Path getParent()
Повертає батьківську директорію
Path getFileName()
Повертає ім'я файлу без директорії
Path getRoot()
Повертає кореневу директорію зі шляху
boolean isAbsolute()
Перевіряє, чи є поточний шлях абсолютним
Path toAbsolutePath()
Перетворює шлях на абсолютний
Path normalize()
Видаляє шаблони в імені директорії
Path resolve(Path other)
Формує новий абсолютний шлях з абсолютного та відносного шляхів
Path relativize(Path other)
Отримує відносний шлях із двох абсолютних шляхів
boolean startsWith(Path other)
Перевіряє, чи поточний шлях починається зі вказаного шляху
boolean endsWith(Path other)
Перевіряє, чи поточний шлях закінчується вказаним шляхом
int getNameCount()
Поділяє шлях на частини роздільником /
і повертає кількість частин
Path getName(int index)
Поділяє шлях на частини роздільником /
і повертає частину шляху за її номером
Path subpath(int beginIndex, int endIndex)
Поділяє шлях на частини роздільником /
і повертає частину шляху, задану інтервалом
File toFile()
Перетворює об'єкт Path на застарілий об'єкт File
URI toUri()
Перетворює об'єкт Path на об'єкт типу URI

Далі наведено короткий опис методів.


3. Поділ шляху на частини

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

Код Значення
String str = "c:\\windows\\projects\\note.txt";
Path path = Path.of(str).getParent();
"c:\\windows\\projects\\"
String str = "c:\\windows\\projects\\";
Path path = Path.of(str).getParent();
"c:\\windows\\"
String str = "c:\\";
Path path = Path.of(str).getParent();
null

Метод getFileName() повертає частину шляху після останнього роздільника, тобто тільки ім'я файлу (або директорії):

Код Значення
String str = "c:\\windows\\projects\\note.txt";
Path path = Path.of(str).getFileName();
"note.txt"
String str = "c:\\windows\\projects\\";
Path path = Path.of(str).getFileName();
"projects"
String str = "c:\\";
Path path = Path.of(str).getFileName();
null

Метод getRoot() повертає шлях до кореневої директорії:

Код Значення
String str = "c:\\windows\\projects\\";
Path path = Path.of(str).getRoot();
"c:\\"


4. Абсолютний і відносний шляхи

Є два типи шляхів: абсолютні й відносні. Абсолютний шлях починається з кореневої директорії. Для Windows це може бути папка c:\, для Linux — директорія /

Відносний шлях вказується відносно певної директорії. Тобто це кінцева частина шляху без початкової. Відносний шлях можна перетворити на абсолютний і навпаки.

Метод boolean isAbsolute()

Метод перевіряє, чи є поточний шлях абсолютним:

Код Значення
String str = "c:\\windows\\projects\\note.txt";
boolean abs = Path.of(str).isAbsolute();
true
String str = "src\\com\\javarush\\Main.java";
boolean abs = Path.of(str).isAbsolute();
false

Метод Path toAbsolutePath()

Перетворює шлях на абсолютний і за потреби додає до нього поточну робочу директорію:

Код Значення
String str = "c:\\windows\\projects\\note.txt";
Path path = Path.of(str).toAbsolutePath();
"c:\\windows\\projects\\note.txt"
String str = "src\\com\\javarush\\Main.java";
Path path = Path.of(str).toAbsolutePath();
"d:\\work\\src\\com\\javarush\\Main.java"

Метод Path normalize()

У шляху замість імені директорії можна писати «..», що означає повернення на одну директорію назад. Нормалізація це усуває. Приклади:

Код Значення
String str = c:\\windows\\..\\projects\\note.txt";
Path path = Paths.of(str).normalize();
"c:\\projects\\note.txt"
String str = "src\\com\\javarush\\..\\Main.java";
Path path = Paths.of(str).normalize();
"src\\com\\Main.java"

Метод Path relativize(Path other)

Метод relativize() дозволяє обчислити «різницю шляхів», тобто показати, чим один шлях відрізняється від іншого.

Код Значення
Path path1 = Path.of("c:\\windows\\projects\\note.txt");
Path path2 = Path.of("c:\\windows\\");
Path result = path2.relativize(path1);
"projects\\note.txt"
Path path1 = Path.of("c:\\windows\\projects\\note.txt");
Path path2 = Path.of("c:\\windows\\");
Path result = path1.relativize(path2);
"..\\.."
Path path1 = Path.of("c:\\aaa\\bbb\\1.txt");
Path path2 = Path.of("d:\\zzz\\y.jpg");
Path result = path1.relativize(path2);
Помилка IllegalArgumentException:
два шляхи мають різний «корінь» (різні диски)

Метод Path resolve(Path other)

Метод resolve() виконує операцію, зворотну relativize(): він формує новий абсолютний шлях з абсолютного і відносного шляхів.

Код Значення
Path path1 = Path.of("projects\\note.txt");
Path path2 = Path.of("c:\\windows\\");
Path result = path1.resolve(path2);
"c:\\windows"
Path path1 = Path.of("projects\\note.txt");
Path path2 = Path.of("c:\\windows\\");
Path result = path2.resolve(path1);
"c:\\windows\\projects\\note.txt"

Метод toFile()

Метод повертає застарілий об'єкт File, який зберігає той самий шлях до файлу, що й об'єкт Path.

Метод toURI()

Метод перетворює шлях відповідно до стандарту URI і повертає об'єкт, який містить шлях до файлу:

Шлях до файлу URI до файлу
c:\windows\projects\note.txt
file:///c:/windows/projects/note.txt