JavaRush /Курси /Java Syntax Zero /Знайомство з файлами

Знайомство з файлами

Java Syntax Zero
Рівень 16 , Лекція 5
Відкрита

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

Коментарі (19)
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ
Андрій Рівень 18
25 квітня 2024
Нарешті дали пояснення до Path😅
Viacheslav B. Рівень 1
2 квітня 2024
я вважаю що для другого завдання можна було би додати підказку що знадобитися використовувати try cath
28 березня 2025
там є підказка, просто не явна. і не обов'язково юзати трай-кетч
Pavlo Kezin Рівень 23
22 вересня 2023
Тільки мені здається, що ця лекція повинна бути однією з перших у цьому рівні... наче хтось зробив реверс у лекціях...
TimpoIngo Рівень 38
7 вересня 2023
Щоб все вчити послідовно, потрібно викликати метод reverse() :)
Serhii #2958832 Рівень 51 Expert
8 червня 2023
Друге завдання: не зрозумів навіщо використовувати relativize() двічі, якщо перше його використання вже викинуло IllegalArgumentException, що за матеріалом лекції значить: два шляхи мають різний «корінь» (різні диски), отже про відносний шлях не може бути й мови. Чи не так? Хто може пояснити?
Yevhenii Рівень 17
6 квітня 2023
Чи підкаже хтось, чому в третьому завданні ця відповідь не підходить boolean abs = Path.of(str).isAbsolute(); System.out.println(abs); if(abs != true) { Path path = Path.of(str).toAbsolutePath(); System.out.println(path); } } }
Diana Javarush Рівень 32
7 квітня 2023
Спробуйте перевірити "якщо abs true то вивід", а в else вже зробити перетворення на абсолют
neeeksa Рівень 23
17 квітня 2023
тут можно сильно укоротить

Path path = Path.of(str);
            boolean abs = path.isAbsolute();
            if(abs)
            {
                path = path.toAbsolutePath();
                System.out.println(path);
            }
1 серпня 2023
System.out.println(path) потрібно вивести за тіло if {..}
Валерій Рівень 33
25 березня 2025
Видали вивід System.out.println(abs); - можливо через це валідатор не приймає, бо зчитує першу строку і бачить, зо то не те що потрібно + boolean abs = Path.of(str).isAbsolute(); //System.out.println(abs); - видали Path path = Path.of(str) if(abs != true) { path = Path.of(str).toAbsolutePath(); System.out.println(path); } } }
Yevhenii Рівень 17
6 квітня 2023
Теж не розумію логіки відповіді другого завдання, теж використовував relativize двічі, але всеодно викидало помилку, таки точно муть якась(
kalkulator¹ Рівень 51
22 листопада 2022
я тут дізнався що лекції після 20 рівня будуть на російській я розчарований((((((((((((((((((((((
kalkulator¹ Рівень 51
20 листопада 2022
аа серйозно? тільки зараз я дізнаюсь шо таке Path,
unite Рівень 24 Expert
25 січня 2023
те ж питання, зачачі актіино використовували path кілька лекцій тому
Anonymous #696530 Рівень 19
3 листопада 2022
Ця лекція краща за попередні в цьому рівні, хоч щось зрозуміло... Завдання "Усе відносне" - якась муть, краще б додали кілька простіших і цікавіших з іншими методами класу Path...
Beisik Рівень 25
25 грудня 2022
я так і не зрозумів логіки цього завдання.Я зробив за 2 години 3 способи виводу але у всіх одна і та ж помилка з виводом relativize двічі.Хоча як раз таки я 2 рази і вивожу як вказано за умовою.