1. URLclasse

Abbiamo studiato come lavorare con i flussi di I/O. Abbiamo studiato lavorare con i file. Cosa dovremmo studiare dopo? Che ne dici di lavorare con la rete, incluso Internet? Sembra promettente, vero?

In Java, lavorare con Internet non è più difficile che lavorare con i file. Beh, forse solo un po'.

Per lavorare con le risorse Internet, Java ha una classe speciale — URL. È semplice come uno sgabello, come vedrai ora.

Ottenere una pagina web

Quante righe di codice pensi di dover scrivere per scaricare da Internet un file di testo e visualizzarne il contenuto sullo schermo? 10? 100? 1000? O forse 5?

Codice Nota
URL url = new URL("https://codegym.cc");
InputStream input = url.openStream();
byte[] buffer = input.readAllBytes();
String str = new String(buffer);
System.out.println(str);
Crea un oggetto URL con il percorso della pagina
Ottiene un InputStreamdall'oggetto URL
Legge tutti i byte e restituisce un array di byte
Converte l'array in una stringa
Visualizza la stringa

Sullo schermo verrà visualizzato il contenuto di un file HTML:

Uscita console
<!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″>
    ...

Confrontando il lavoro con FileeURL

URLè simile a Fileo Path, ma Pathmemorizza il percorso di una risorsa nel file system e URLmemorizza il percorso di una risorsa su Internet.

Tutta la magia accade quando otteniamo un InputStreamoggetto grazie a una singola chiamata al openStream()metodo. Questo è un oggetto ordinario e lo abbiamo già studiato dentro e fuori. Tutto diventa ovvio dopo che otteniamo l' InputStreamoggetto. Dopotutto, sappiamo già come ottenere dati da esso.

Dai un'occhiata: solo le prime due righe sono diverse, e solo leggermente. E ora puoi vederlo: il vantaggio della standardizzazione e del lavoro con catene di flussi di dati:

Lavorare con Internet Lavorare con un file
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. URLConnectionclasse

Oltre a leggere semplicemente i dati da Internet, possiamo anche caricare i dati. Caricare i dati è molto più complicato che leggerli. Avrai bisogno di qualche altro metodo. Per esempio:

Codice Nota
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
Crea un oggetto URL con il percorso della pagina
Crea una connessione bidirezionale


Ottieni un flusso di output
Inserisci i dati in esso


Ottieni un flusso di input
Leggi i dati da esso

Si noti che qui non chiamiamo più il url.openStream()metodo. Invece, prendiamo un percorso più lungo:

  • Per prima cosa stabiliamo una connessione bidirezionale stabile utilizzando il URLConnection.openConnection()metodo
  • Quindi otteniamo un flusso per inviare i dati utilizzando il connection.getOutputStream()metodo e inviare i dati al server
  • Quindi otteniamo un flusso per leggere i dati utilizzando il connection.getInputStream()metodo e iniziamo a leggere i dati da esso.

Gestione delle risorse

A rigor di termini, dovremmo avvolgere tutti i flussi in un try-with-resourcesblocco per una gestione sicura. E non sarebbe male avvolgere il nudo InputStreame OutputStreamin qualcosa di più conveniente. Ad esempio, in PrintStreame BufferedReader.

Se facciamo tutto questo, il nostro codice sarà simile a questo:

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. Esempi di lavoro con la rete

Scarichiamo qualcosa da Internet. E non solo scaricarlo, ma salvarlo su disco.

Ad esempio, scriviamo un programma che salva su disco un'immagine dalla home page di Google.

In linea di principio, non c'è niente di complicato qui. Nella sua forma più semplice, questo codice sarebbe simile a questo:

Salvataggio di un file su disco
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);

Con l'aiuto delle prime tre righe, riceviamo un flusso di dati da una risorsa Internet, da un'immagine.

Nella quarta riga, creiamo il nome del file in cui salveremo l'immagine. Il nome può essere qualsiasi cosa, ma l'estensione del file deve corrispondere all'estensione dell'immagine su Internet. Ciò consentirà ai visualizzatori di immagini locali di aprirlo correttamente.

E infine, l'ultima riga è uno dei metodi Filesdella classe copy. La Filesclasse ne ha diversi. Questo metodo, che abbiamo utilizzato, accetta un flusso di byte ( InputStream) come primo parametro e come secondo parametro, il nome del file in cui devono essere scritti i dati.

Teoricamente, se i URLcaratteri dell'immagine fossero brevi, allora questo codice potrebbe anche essere scritto in una sola riga:

Copia di dati da un flusso a un file
Files.copy(
   new URL("https://www.google.com/logo.png").openStream(),
   Path.of("c:\\GoogleLogo.png")
);

Naturalmente, non è necessario scriverlo in questo modo, ma questo esempio dimostra quanto siano convenienti e potenti i flussi di I/O in Java.