1. URLклас

Учor сме работа с I/O потоци. Учихме да работим с файлове. Какво следва да учим? Какво ще кажете за работата с мрежата, включително Интернет? Звучи обещаващо, нали?

В Java работата с интернет не е по-трудна от работата с файлове. Е, може би само малко.

За да работи с интернет ресурси, Java има специален клас — URL. Толкова е просто като табуретка, Howто ще видите сега.

Получаване на уеб page

Колко реда code мислите, че трябва да напишете, за да изтеглите текстов файл от Интернет и да покажете съдържанието му на екрана? 10? 100? 1000? Или може би 5?

Код Забележка
URL url = new URL("https://codegym.cc");
InputStream input = url.openStream();
byte[] buffer = input.readAllBytes();
String str = new String(buffer);
System.out.println(str);
Създава URL обект с пътя към pageта
Получава InputStreamот URL обекта
Чете всички byteове и връща масив от byteове
Преобразува масива в низ
Показване на низа

Съдържанието на 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е подобен на Fileor Path, но Pathсъхранява пътя до ресурс във файловата система и URLсъхранява пътя до ресурс в Интернет.

Цялата магия се случва, когато получим InputStreamобект благодарение на едно извикване на openStream()метода. Това е обикновен обект и вече сме го проучor отвътре и отвън. Всичко става очевидно, след като получим InputStreamобекта. В крайна сметка ние вече знаем How да получим данни от него.

Погледнете: само първите два реда са различни и то съвсем малко. И сега можете да го видите — предимството на стандартизацията и работата с вериги от потоци от данни:

Работа с Интернет Работа с файл
URL url = new URL("https://codegym.cc");
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);


2. URLConnectionклас

В допълнение към простото четене на данни от интернет, можем също да качваме данни. Качването на данни е много по-сложно от четенето им. Ще ви трябват още няколко метода. Например:

Код Забележка
URL url = new URL("https://codegym.cc");
URLConnection connection = url.openConnection();

// Get a stream for sending data
OutputStream output = connection.getOutputStream();
output.write(1); // Send data

// Get a stream for reading data
InputStream input = connection.getInputStream();
int data = input.read(); // Read data
Създаване на URL обект с пътя към pageта
Създаване на двупосочна връзка


Получаване на изходен поток
Поставете данни в него


Получаване на входен поток
Четене на данни от него

Имайте предвид, че вече не извикваме url.openStream()метода тук. Вместо това поемаме по по-дълъг маршрут:

  • Първо установяваме стабилна двупосочна връзка с помощта на URLConnection.openConnection()метода
  • След това получаваме поток за изпращане на данни с помощта на connection.getOutputStream()метода и изпращане на данни към сървъра
  • След това получаваме поток за четене на данни с помощта на connection.getInputStream()метода и започваме да четем данни от него.

Управление на ресурси

Строго погледнато, трябва да увием всички потоци в try-with-resourcesблок за безопасно боequalsе. И няма да е зле да увиете голото InputStreamи OutputStreamв нещо по-удобно. Например в PrintStreamи BufferedReader.

Ако направим всичко това, нашият code ще изглежда така:

URL url = new URL("https://codegym.cc");
URLConnection connection = url.openConnection();

// Send data
try (OutputStream output = connection.getOutputStream();
   PrintStream sender = new PrintStream(output))
{
   sender.println("Hello");
}

// Read data
try(InputStream input = connection.getInputStream();
   BufferedReader reader = new BufferedReader(new InputStreamReader(input)))
{
   while (reader.ready())
      System.out.println(reader.readLine());
}

3. Примери за работа с мрежата

Да изтеглим нещо от интернет. И не просто го изтеглете, но го запишете на диск.

Например, нека напишем програма, която записва изображение от началната page на Google на диск.

По принцип тук няма нищо сложно. В най-простата си форма този code ще изглежда така:

Запазване на файл на диск
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);

С помощта на първите три реда получаваме поток от данни от интернет ресурс - от картина.

В четвъртия ред създаваме името на file, в който ще запазим изображението. Името може да бъде всяко, но разширението на file трябва да съвпада с разширението на снимката в Интернет. Това ще позволи на местните зрители на изображения да го отворят правилно.

И накрая, последният ред е един от методите Filesна класа copy. Класът Filesима няколко от тях. Този метод, който използвахме, приема InputStreamкато първи параметър поток от byteове ( ), а като втори параметър — името на file, в който трябва да се записват данните.

Теоретично, ако изображението URLбеше кратко, тогава този code може дори да бъде написан в един ред:

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

Разбира се, не е нужно да го пишете по този начин, но този пример демонстрира колко удобни и мощни са I/O потоците в Java.