1. OutputStreamclasa

Am explorat recent fluxurile de intrare. Este timpul să vorbim despre fluxurile de ieșire.

Clasa OutputStreameste clasa părinte pentru toate clasele care acceptă ieșirea de octeți. Aceasta este o clasă abstractă care nu face nimic pe cont propriu, dar are clase descendente pentru fiecare ocazie.

Sună extrem de complicat. Pentru a spune mai simplu, această clasă operează pe octeți și nu, de exemplu, caractere sau alte tipuri de date. Iar faptul că este abstract înseamnă că de obicei nu îl folosim, ci mai degrabă una dintre clasele sale descendențe. De exemplu, FileOutputStreamși altele asemenea.

Dar înapoi la OutputStreamclasă. Această clasă are metode pe care toate clasele sale descendente trebuie să le implementeze. Iată pe cele principale:

Metode Descriere
void write(int b)
Scrie un octet (nu un int) în flux.
void write(byte[] buffer)
Scrie o matrice de octeți în flux
void write(byte[] buffer, off, len)
Scrie o parte dintr-o matrice de octeți în flux
void flush()
Scrie toate datele stocate în buffer în flux
void close()
Închide fluxul

Când creați un obiect dintr-o clasă care moștenește InputStream, de obicei specificați un obiect sursă InputStreamdin care citește datele. Când creați un obiect dintr-o clasă care moștenește OutputStream, de obicei specificați și obiectul țintă sau fluxul în care vor fi scrise datele.

Să trecem pe scurt prin toate metodele clasei OutputStream:

write(int b)metodă

Această metodă scrie un octet (nu un int) în fluxul de ieșire. Valoarea transmisă este transformată într-un octet, iar primii trei octeți ai intului sunt aruncați.

write(byte[] buffer)metodă

Scrie matricea dată de octeți în fluxul de ieșire. Asta este.

write(byte[] buffer, int offset, int length)metodă

Scrie o porțiune din matricea de octeți transmisă în fluxul de ieșire. Variabila offset indică indexul primului element al matricei și lengtheste lungimea subsetului de scris.

flush()metodă

Metoda flush()este folosită pentru a forța orice date stocate în buffer în fluxul curent să fie scrise în fluxul țintă. Acest lucru este relevant atunci când se utilizează buffering și/sau mai multe obiecte de flux aranjate într-un lanț.

close()metodă

Scrie orice date nescrise în obiectul țintă. Metoda close()nu trebuie apelată dacă utilizați un try-with-resourcesbloc.

Exemplu de copiere a unui fișier

Cod Notă
String src = "c:\\projects\\log.txt";
String dest = "c:\\projects\\copy.txt";

try(FileInputStream input = new FileInputStream(src);
FileOutputStream output = new FileOutputStream(dest))
{
   byte[] buffer = new byte[65536]; // 64Kb
   while (input.available() > 0)
   {
      int real = input.read(buffer);
      output.write(buffer, 0, real);
   }
}



InputStreampentru citirea dintr-un fișier
OutputStreampentru scriere într-un fișier

Buffer în care vom citi datele
Atâta timp cât există date în flux

Citiți date în buffer
Scrieți datele din buffer în al doilea flux

2. Writerclasa

Clasa Writereste exact aceeași cu OutputStreamclasa, dar încă o dată o diferență: funcționează cu caractere ( char) în loc de octeți.

Aceasta este o clasă abstractă: nu puteți crea obiecte ale Writerclasei. Scopul său principal este să fie o clasă părinte comună pentru sute de clase descendente și să le ofere metode comune de lucru cu fluxurile de caractere.

Metode ale Writerclasei (și toate clasele sale descendente):

Metode Descriere
void write(int b)
Scrie un caracter (nu un int) în flux.
void write(char[] buffer)
Scrie o matrice de caractere în flux
void write(char[] buffer, off, len)
Scrie o parte dintr-o matrice de caractere în flux
void write(String str)
Scrie un șir în flux
void write(String str, off, len)
Scrie o parte dintr-un șir în flux
void flush()
Scrie toate datele stocate în buffer în flux
void close()
Închide fluxul

Metodele sunt foarte asemănătoare cu metodele clasei OutputStream, dar funcționează cu caractere în loc de octeți.

Descrierea metodelor:

write(int b)metodă

Această metodă scrie un singur caracter ( char— nu un int) în fluxul de ieșire. Valoarea transmisă este turnată la un char, iar primii doi octeți sunt eliminați.

write(char[] buffer)metodă

Scrie matricea dată de caractere în fluxul de ieșire.

write(char[] buffer, int offset, int length)metodă

Scrie o parte din matricea de caractere transmisă în fluxul de ieșire. Variabila offsetindică indexul primului element al matricei și lengtheste lungimea submulțimii care trebuie scrisă.

write(String str)metodă

Scrie șirul dat în fluxul de ieșire.

write(String str, int offset, int length)metodă

Scrie o porțiune din șirul dat în fluxul de ieșire: șirul este convertit într-o matrice de caractere. Variabila offsetindică indexul primului element al matricei și lengtheste lungimea submulțimii care trebuie scrisă.

flush()metodă

Metoda flush()este folosită pentru a forța orice date stocate în buffer în fluxul curent să fie scrise în fluxul țintă. Acest lucru este relevant atunci când se utilizează buffering și/sau mai multe obiecte de flux aranjate într-un lanț.

close()metodă

Scrie orice date nescrise în obiectul țintă. Metoda close()nu trebuie apelată dacă utilizați un try-with-resourcesbloc.

Exemplu de program care copiază un fișier text:

Cod Notă
String src = "c:\\projects\\log.txt";
String dest = "c:\\projects\\copy.txt";

try(FileReader reader = new FileReader(src);
FileWriter writer = new FileWriter(dest))
{
   char[] buffer = new char[65536]; // 128Kb
   while (reader.ready())
   {
      int real = reader.read(buffer);
      writer.write(buffer, 0, real);
   }
}



Readerpentru citirea dintr-un fișier
Writerpentru scrierea într-un fișier

Buffer în care vom citi datele
Atâta timp cât există date în flux

Citiți date într-un buffer
Scrieți datele din buffer în al doilea flux

StringWriterclasă

Există o altă clasă interesantă care moștenește Writerclasa: se numește StringWriter. Conține un șir mutabil - un StringBufferobiect. Și de fiecare dată când „scrieți” ceva obiectului StringWriter, textul este pur și simplu adăugat în buffer-ul său intern.

Exemplu:

Cod Notă
StringWriter writer = new StringWriter();
writer.write("Hello");
writer.write(String.valueOf(123));

String result = writer.toString();
StringWriterEste creat un flux de caractere țintă ( )
Un șir este scris în buffer-ul din interiorul StringWriter
Un șir este scris în buffer-ul din interiorul StringWriter

Conversia conținutului unui obiect într-un șir

În acest caz, StringWriterclasa este în esență un wrapper peste StringBufferclasă, dar StringWriterclasa este un descendent al Writerclasei stream și poate fi folosită în lanțuri de obiecte stream. Aceasta este o proprietate destul de utilă în practică.



3. PrintStreamclasa

Clasele de flux de ieșire pot fi, de asemenea, puse într-un lanț cu fluxuri intermediare care scriu date în fluxul țintă transmis acestora. Vederea generală a interacțiunii acestor fluxuri arată astfel:

Clasa PrintStream

Cel mai interesant și versatil dintre toate fluxurile de ieșire intermediare este PrintStream. Are zeci de metode și până la 12 constructori.

Clasa PrintStreammoștenește FilterOutputStreamclasa, care moștenește OutputStream. Aceasta înseamnă că PrintStreamclasa are toate metodele claselor părinte în plus față de propriile sale metode . Iată cele mai interesante:

Metode Descriere
void print(obj)
Convertește obiectul transmis într-un șir și îl trimite în fluxul țintă.
void println(obj)
Convertește obiectul transmis într-un șir și îl trimite în fluxul țintă. Adaugă o întrerupere de linie la sfârșit
void println()
Afișează un caracter de întrerupere de linie către fluxul țintă
PrintStream format(String format, args...)
Construiește și scoate un șir pe baza șirului de format și a argumentelor transmise; similar cu String.format()metoda

Și unde sunt aceste zeci de metode, vă întrebați?

Ei bine, are multe variante ale metodelor print()și println()cu parametri diferiți. Ele pot fi rezumate în acest tabel.

Nu ne vom scufunda în aceste metode, pentru că le cunoașteți deja bine. Poți ghici la ce ajung?

iti amintesti System.out.println()? Dar poate fi scris în două rânduri:

Cod Ieșire de consolă
PrintStream stream = System.out;
stream.println("Hello!");
Hello!

Comanda noastră preferată este un apel la metoda pe variabila statică a clasei. Și tipul acestei variabile este .System.out.println()println()outSystemPrintStream

În multe niveluri CodeGym și în aproape fiecare sarcină, ați apelat metode ale PrintStreamclasei fără să știți!

Uz practic

Java are această clasă interesantă numită ByteArrayOutputStream, care este o matrice de octeți în creștere dinamică care moștenește OutputStream.

Un ByteArrayOutputStreamobiect și PrintStreamun obiect pot fi înlănțuite astfel:

Cod Descriere
ByteArrayOutputStream baos = new ByteArrayOutputStream();

try(PrintStream stream = new PrintStream(baos))
{
   stream.println("Hello");
   stream.println(123);
}

String result = baos.toString();

System.out.println(result);
Creați un buffer de scriere în memorie

Înfășurați tamponul într-un PrintStreamobiect

Scrieți date pe consolă



Transformați matricea într-un șir!

Ieșire din consolă:
Hello!
123