"Hej, Amigo! I dag skal vi igen grave i, hvordan InputStream og OutputStream fungerer. Den indledende forklaring var faktisk lidt forenklet. Det er ikke grænseflader. Det er abstrakte klasser, og de har endda et par implementerede metoder. Lad os tage et kig på de metoder, de har:"

InputStream metoder Hvad metoden gør
int read(byte[] buff);
Denne metode læser straks en blok af bytes ind i bufferen ( byte array ), indtil bufferen er fuld, eller indtil kilden ikke har flere bytes at læse.
Metoden returnerer antallet af faktisk læste bytes (som kan være mindre end længden af ​​arrayet)
int read();
Denne metode læser en byte og returnerer den. Resultatet udvides til en int for udseende. Hvis der ikke er flere bytes at læse, returnerer metoden -1.
int available();
Denne metode returnerer antallet af ulæste (tilgængelige) bytes.
void close();
Denne metode «lukker» strømmen. Du kalder dette, når du er færdig med at arbejde med streamen.
Objektet udfører derefter de nødvendige husholdningsoperationer for at lukke filen osv.
På dette tidspunkt kan du ikke læse flere data fra strømmen.

"Så vi kan læse ikke kun enkelte bytes, men også hele blokke?"

"Nemlig."

"Kan vi også skrive hele blokke?"

"Ja, tjek det ud:"

OutputStream metoder Hvad metoden gør
void write(int c);
Denne metode skriver en byte. Int-typen er indsnævret til en byte. Den ekstra del kasseres simpelthen.
void write(byte[] buff);
Denne metode skriver en blok af bytes.
void write(byte[] buff, int from, int count);
Denne metode skriver en del af en blok af bytes. Det bruges i tilfælde, hvor byte-arrayet måske ikke er blevet udfyldt helt.
void flush();
Hvis strømmen internt gemmer data, der endnu ikke er blevet skrevet, tvinger denne metode det til at blive skrevet.
void close();
Denne metode «lukker» strømmen. Du kalder dette, når du er færdig med at arbejde med streamen.
Objektet udfører derefter de nødvendige husholdningsoperationer for at lukke filen osv. Du kan ikke længere skrive data til streamen, og flush kaldes automatisk.

"Hvordan ville filkopieringskoden se ud, hvis vi læser hele blokke ad gangen i stedet for enkelte bytes?"

"Hmm. Noget i stil med 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 hvad er denne tællevariabel?"

"Når vi læser den seneste blok af data fra en fil, kan vi f.eks. få 328 bytes i stedet for 1000. Så når vi skriver dataene, skal vi angive, at vi ikke skriver hele blokken – kun de første 328 bytes."

Når vi læser den sidste blok, vil læsemetoden returnere antallet af faktisk læste bytes. 1000 hver gang vi læser en blok, bortset fra den sidste blok, hvor vi får 328.

Så når vi skriver en blok, angiver vi, at ikke alle bytes i bufferen skal skrives, kun 328 (dvs. værdien gemt i tællevariablen).

"Nu er det hele klart. Tak, Ellie."