„Bună ziua, Amigo! Astăzi vom cerceta din nou cum funcționează InputStream și OutputStream . Explicația inițială a fost de fapt puțin simplistă. Acestea nu sunt interfețe. Sunt clase abstracte și au chiar și câteva metode implementate. Să aruncăm o privire la metodele pe care le au:"

Metode InputStream Ce face metoda
int read(byte[] buff);
Această metodă citește imediat un bloc de octeți în tampon ( byte array ), până când tamponul este plin sau până când sursa nu mai are alți octeți de citit.
Metoda returnează numărul de octeți citiți efectiv (care poate fi mai mic decât lungimea matricei)
int read();
Această metodă citește un octet și îl returnează. Rezultatul este extins la un int pentru aspect. Dacă nu mai există octeți de citit, metoda returnează -1.
int available();
Această metodă returnează numărul de octeți necitiți (disponibili).
void close();
Această metodă „închide” fluxul. Numiți asta când ați terminat de lucrat cu fluxul.
Obiectul efectuează apoi operațiunile de întreținere necesare închiderii fișierului etc.
În acest moment, nu mai puteți citi date din flux.

„Deci putem citi nu numai octeți unici, ci și blocuri întregi?”

"Exact."

„Putem scrie și blocuri întregi?”

"Da, verifică:"

Metode OutputStream Ce face metoda
void write(int c);
Această metodă scrie un octet. Tipul int este restrâns la un octet. Partea suplimentară este pur și simplu aruncată.
void write(byte[] buff);
Această metodă scrie un bloc de octeți.
void write(byte[] buff, int from, int count);
Această metodă scrie o parte dintr-un bloc de octeți. Este folosit în cazurile în care matricea de octeți poate să nu fi fost umplută în întregime.
void flush();
Dacă fluxul stochează intern orice date care nu au fost încă scrise, această metodă forțează să fie scrisă.
void close();
Această metodă „închide” fluxul. Numiți asta când ați terminat de lucrat cu fluxul.
Obiectul efectuează apoi operațiunile de întreținere necesare pentru a închide fișierul etc. Nu mai puteți scrie date în flux, iar fluxul este apelat automat.

„Cum ar arăta codul de copiere a fișierelor dacă citim blocuri întregi odată în loc de octeți unici?”

"Hmm. Ceva de genul asta:"

Copiați un fișier pe disc
public static void main(String[] args) throws Exception
{
 //Create a stream to read bytes from a file
 FileInputStream inputStream = new FileInputStream("c:/data.txt");
 //Create a stream to write bytes to a file
 FileOutputStream outputStream = new FileOutputStream("c:/result.txt");

  byte[] buffer = new byte[1000];
 while (inputStream.available() > 0) //as long as there are unread bytes
 {
  //Read the next block of bytes into buffer, and store the actual number of bytes read in count.
  int count = inputStream.read(buffer);
  outputStream.write(buffer, 0, count); //Write a block (part of a block) to the second stream
 }

 inputStream.close(); //Close both streams. We don't need them any more.
 outputStream.close();
}

„Înțeleg totul despre buffer, dar care este această variabilă de numărare?”

„Când citim cel mai recent bloc de date dintr-un fișier, putem obține, să zicem, 328 de octeți în loc de 1000. Deci, atunci când scriem datele, trebuie să indicăm că nu scriem întregul bloc - doar primii 328. octeți”.

Când citim ultimul bloc, metoda read va returna numărul de octeți citiți efectiv. 1000 de fiecare dată când citim un bloc, cu excepția ultimului bloc, când obținem 328.

Deci, atunci când scriem un bloc, indicăm că nu toți octeții din buffer ar trebui să fie scrieți, doar 328 (adică valoarea stocată în variabila count).

— Acum e totul clar. Mulţumesc, Ellie.