JavaRush/Курси/Java Syntax Zero/Робота з мережею

Робота з мережею

Відкрита

1. Клас URL

Роботу з потоками вводу й виводу ми вже вивчили, роботу з файлами вивчили. То що ж вивчати далі? А як щодо роботи з мережею та інтернетом? Звучить заманливо, чи не так?

У Java працювати з інтернетом не складніше, ніж працювати з файлами. Ну хіба що трошечки.

Для роботи з ресурсами в інтернеті в Java є спеціальний клас — URL. Він не складніший за табуретку, і ви зараз у цьому переконаєтеся.

Отримання сторінки з інтернету

На вашу думку, скільки рядків коду потрібно написати, щоб завантажити який-небудь текстовий файл з інтернету й відобразити його вміст на екрані? 10? 100? 1000? А може, 5?

Код Примітка
URL url = new URL("https://javarush.com");
InputStream input = url.openStream();
byte[] buffer = input.readAllBytes();
String str = new String(buffer);
System.out.println(str);
Створюємо об'єкт URL зі шляхом до сторінки
Отримуємо InputStream від інтернет-об'єкта
Читаємо всі байти й отримуємо масив байтів
Перетворюємо масив на рядок
Виводимо рядок на екран

На екрані відобразиться вміст HTML-файлу:

Виведення на екран
<!DOCTYPE html><html lang="ru" class="light"><head>
    <meta charset="utf-8″>
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1″>
    ...

Порівняння роботи класів File і URL

Клас URL дуже схожий на класи File і Path, тільки Path зберігає шлях до ресурсу у файловій системі, а URL — шлях до ресурсу в інтернеті.

Вся магія в тому, що один виклик методу openStream() дає змогу відразу отримати об'єкт типу InputStream. А це стандартний об'єкт, і ми його вже вивчили вздовж і впоперек. Все стає наочним уже після отримання об'єкта типу InputStream. Адже як зчитувати з нього дані, ми вже знаємо.

Порівняйте: відрізняються тільки два перші рядки, та й то зовсім трохи. От вона — перевага стандартизації та роботи з ланцюжками потоків даних:

Робота з інтернетом Робота з файлом
URL url = new URL("https://javarush.com");
InputStream input = url.openStream();
byte[] buffer = input.readAllBytes();
String str = new String(buffer);
System.out.println(str);
File file = new File("c:\\readme.txt");
InputStream input = new FileInputStream(file);

byte[] buffer = input.readAllBytes();
String str = new String(buffer);
System.out.println(str);

16
Задача
Java Syntax Zero,  16 рівень,  7 лекція
Недоступна
Тимчасове збереження файлу
Тимчасове збереження файлу

2. Клас URLConnection

Крім простого читання даних з інтернету, ми також можемо передавати туди дані. Передавання даних — це набагато складніший процес, ніж читання. Для цього доведеться використати додаткові методи. Приклад:

Код Примітка
URL url = new URL("https://javarush.com");
URLConnection connection = url.openConnection();

// отримали потік для надсилання даних
OutputStream output = connection.getOutputStream();
output.write(1); // надсилаємо дані

// отримали потік для читання даних
InputStream input = connection.getInputStream();
int data = input.read(); // читаємо дані
Створюємо об'єкт URL зі шляхом до сторінки
Створюємо двостороннє з'єднання


Отримуємо потік виводу
Виводимо в нього дані


Отримуємо потік вводу
Читаємо з нього дані

Зверніть увагу, що тут ми не викликаємо метод url.openStream(). Натомість ми йдемо довшим шляхом:

  • Спочатку ми встановлюємо стабільне двостороннє з'єднання за допомогою методу URLConnection openConnection()
  • Потім отримуємо потік для надсилання даних за допомогою методу connection.getOutputStream() і надсилаємо дані на сервер
  • Потім отримуємо потік для читання даних за допомогою методу connection.getInputStream() і починаємо читати з нього дані.

Контроль ресурсів

Для безпечної роботи варто обгорнути всі потоки оператором try-with-resources. Також не завадить обгорнути голі InputStream і OutputStream чимось зручнішим — скажімо, класами PrintStream і BufferedReader.

Якщо ми все це зробимо, наш код матиме такий вигляд:

URL url = new URL("https://javarush.com");
URLConnection connection = url.openConnection(); // надсилаємо дані
try (OutputStream output = connection.getOutputStream();
   PrintStream sender = new PrintStream(output))
{
   sender.println("Привіт");
}

// читаємо дані
try(InputStream input = connection.getInputStream();
   BufferedReader reader = new BufferedReader(new InputStreamReader(input)))
{
   while (reader.ready())
      System.out.println(reader.readLine());
}

3. Приклади роботи з мережею

Спробуймо щось завантажити з інтернету. І не просто завантажити, а зберегти на диску.

Для прикладу спробуймо написати програму, що зберігає на диск картинку з головної сторінки Google.

Це нескладно. Найпростішій варіант цього коду буде таким:

Збереження файлу на диск
String image = "https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png";
URL url = new URL(image);
InputStream input = url.openStream();

Path path = Path.of("c:\\GoogleLogo.png");
Files.copy(input, path);

За допомогою трьох перших рядків ми отримуємо потік даних з інтернет-ресурсу — з картинки.

У четвертому рядку ми створюємо ім'я файлу, в який збережемо картинку. Ім'я може бути довільним, але розширення імені файлу має збігатися з розширенням імені картинки в інтернеті. Тоді локальні програми перегляду картинок будуть правильно її відкривати.

І нарешті, останній рядок — це один із методів copy класу Files. Клас Files має їх декілька. Метод, який ми використали, отримує в першому параметрі джерело даних — байтовий потік (InputStream), а в другому параметрі — ім'я файлу, куди потрібно записати дані.

Теоретично, якби URL-адреса картинки була короткою, цей код взагалі можна було б записати в один рядок:

Копіювання даних з потоку в файл
Files.copy(
   new URL("https://www.google.com/logo.png").openStream(),
   Path.of("c:\\GoogleLogo.png")
);

Так писати, звісно, не слід, проте цей приклад демонструє, наскільки зручними й потужними є потоки вводу-виводу в Java.


16
Задача
Java Syntax Zero,  16 рівень,  7 лекція
Недоступна
Отримання інформації через API
Отримання інформації через API
16
Задача
Java Syntax Zero,  16 рівень,  7 лекція
Недоступна
Отримання інформації через API
Отримання інформації через API
Коментарі (8)
  • популярні
  • нові
  • старі
Щоб залишити коментар, потрібно ввійти в систему
Viacheslav B. System Administrator
5 квітня 2024, 19:13
цей урівень треба читати або два рази або починати з кінця, хто знає - це мабуть така логіка у автора була !
Olexandr
Рівень 16
24 січня 2024, 13:14
Там де частина - Контроль ресурсів і приклад коду - сдається мені, що код працювати не буде, без розблокування потоку виводу... Це я останню задачу робив, точно знаю тепер😃
Sava_crosava Професор кулінарних наук в НУ "Собачий рай"
25 жовтня 2023, 17:55
Раджу ознайомитись із статтею https://javarush.com/groups/posts/4039-vvod-vihvod-v-java-klassih-fileinputstream-fileoutputstream-bufferedinputstream тоді вже можна освідомленно розвязувати задачі) лекція не те щоб жахлива але не повна, застаріла, не розкрита, не цікава, ну можливо все ж жахлива(
Andriy
Рівень 26
24 червня 2023, 14:31
"отримати об'єкт типу InputStream. А це стандартний об'єкт, і ми його вже вивчили вздовж і впоперек" Як прочитав, то так сміявся, що аж щоки боліли. Ага, звісно, "вивчили вздовж і впоперек" 🤣
Shura
Рівень 20
22 липня 2023, 16:37
теж розсмішило це вздовж і впоперек )). і коли, цікаво, ми це встигли
Ihor Prokudin
Рівень 51
29 березня 2023, 07:25
Вже простіше ніж попередні лекці
FAUST_ua
Рівень 29
12 вересня 2022, 20:13
Де до першої задачі пояснено 2 останні строчки коду розв'язання?
Yurii Sakharuk Java Developer
25 травня 2022, 19:02
Жахливий весь блок про ІО. Інформація подається непослідовно, перескакуєте від класу до класу без послідовності та нормального пояснення, частина матеріалу не актуальна, задачі не відповідають інформації з лекцій.