"Hei, Amigo! I dag skal vi igjen grave i hvordan InputStream og OutputStream fungerer. Den første forklaringen var egentlig litt forenklet. Dette er ikke grensesnitt. De er abstrakte klasser, og de har til og med et par implementerte metoder. La oss ta en titt på metodene de har:"

InputStream-metoder Hva metoden gjør
int read(byte[] buff);
Denne metoden leser umiddelbart en blokk med byte inn i bufferen ( byte array ), til bufferen er full eller til kilden ikke har flere byte å lese.
Metoden returnerer antallet byte som faktisk er lest (som kan være mindre enn lengden på matrisen)
int read();
Denne metoden leser en byte og returnerer den. Resultatet utvides til en int for utseende. Hvis det ikke er flere byte å lese, returnerer metoden -1.
int available();
Denne metoden returnerer antall uleste (tilgjengelige) byte.
void close();
Denne metoden «lukker» strømmen. Du kaller dette når du er ferdig med å jobbe med strømmen.
Objektet utfører deretter rengjøringsoperasjonene som trengs for å lukke filen osv.
På dette tidspunktet kan du ikke lese flere data fra strømmen.

"Så vi kan lese ikke bare enkeltbyte, men også hele blokker?"

"Nøyaktig."

"Kan vi også skrive hele blokker?"

"Ja, sjekk det ut:"

OutputStream-metoder Hva metoden gjør
void write(int c);
Denne metoden skriver én byte. Int-typen er begrenset til en byte. Den ekstra delen kastes ganske enkelt.
void write(byte[] buff);
Denne metoden skriver en blokk med byte.
void write(byte[] buff, int from, int count);
Denne metoden skriver en del av en blokk med byte. Den brukes i tilfeller der byte-arrayen kanskje ikke er helt fylt.
void flush();
Hvis strømmen internt lagrer data som ennå ikke er skrevet, tvinger denne metoden til å skrives.
void close();
Denne metoden «lukker» strømmen. Du kaller dette når du er ferdig med å jobbe med strømmen.
Objektet utfører deretter rengjøringsoperasjonene som trengs for å lukke filen osv. Du kan ikke lenger skrive data til strømmen, og flush kalles automatisk.

"Hvordan ville filkopieringskoden se ut hvis vi leser hele blokker om gangen i stedet for enkeltbyte?"

"Hmm. Noe sånt som dette:"

Kopier en fil på disken
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();
}

"Jeg forstår alt om bufferen, men hva er denne tellevariabelen?"

"Når vi leser den siste blokken med data fra en fil, kan vi få for eksempel 328 byte i stedet for 1000. Så når vi skriver dataene, må vi indikere at vi ikke skriver hele blokken – bare de første 328 bytes."

Når vi leser den siste blokken, vil lesemetoden returnere antallet byte som faktisk er lest. 1000 hver gang vi leser en blokk, bortsett fra den siste blokken, når vi får 328.

Så når vi skriver en blokk, indikerer vi at ikke alle bytene i bufferen skal skrives, bare 328 (dvs. verdien som er lagret i tellevariabelen).

"Nå er alt klart. Takk, Ellie."