1. OutputStreamklasse

We hebben onlangs inputstromen verkend. Het is tijd om over outputstromen te praten.

De OutputStreamklasse is de bovenliggende klasse voor alle klassen die byte-uitvoer ondersteunen. Dit is een abstracte klasse die niets uit zichzelf doet, maar voor elke gelegenheid afstammelingen heeft.

Het klinkt buitengewoon ingewikkeld. Simpel gezegd, deze klasse werkt op bytes en niet op bijvoorbeeld tekens of andere gegevenstypen. En het feit dat het abstract is, betekent dat we het meestal niet gebruiken, maar eerder een van zijn afstammelingen. Bijvoorbeeld, FileOutputStreamen dergelijke.

Maar terug naar de OutputStreamklas. Deze klasse heeft methoden die alle onderliggende klassen moeten implementeren. Dit zijn de belangrijkste:

methoden Beschrijving
void write(int b)
Schrijft één byte (geen int) naar de stream.
void write(byte[] buffer)
Schrijft een reeks bytes naar de stream
void write(byte[] buffer, off, len)
Schrijft een deel van een reeks bytes naar de stream
void flush()
Schrijft alle gegevens die in de buffer zijn opgeslagen naar de stream
void close()
Sluit de stroom af

Wanneer u een object maakt van een klasse die overerft InputStream, geeft u meestal een bronobject op waarvan de InputStreamgegevens worden gelezen. Wanneer u een object maakt van een klasse die overerft OutputStream, specificeert u meestal ook het doelobject of de doelstroom waarnaar gegevens worden geschreven.

Laten we kort alle methoden van de klasse doornemen OutputStream:

write(int b)methode

Deze methode schrijft één byte (geen int) naar de uitvoerstroom. De doorgegeven waarde wordt naar een byte gegoten en de eerste drie bytes van de int worden weggegooid.

write(byte[] buffer)methode

Schrijft de gegeven reeks bytes naar de uitvoerstroom. Dat is het.

write(byte[] buffer, int offset, int length)methode

Schrijft een deel van de doorgegeven reeks bytes naar de uitvoerstroom. De offset-variabele geeft de index van het eerste element van de array aan en lengthis de lengte van de subset die moet worden geschreven.

flush()methode

De flush()methode wordt gebruikt om alle potentieel gebufferde gegevens in de huidige stroom te forceren om naar de doelstroom te schrijven. Dit is relevant bij het gebruik van buffering en/of meerdere stream-objecten die in een keten zijn gerangschikt.

close()methode

Schrijft alle ongeschreven gegevens naar het doelobject. De close()methode hoeft niet te worden aangeroepen als u een try-with-resourcesblok gebruikt.

Voorbeeld van het kopiëren van een bestand

Code Opmerking
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);
   }
}



InputStreamvoor het lezen van een bestand
OutputStreamvoor het schrijven naar een bestand

Buffer waarin we de gegevens zullen lezen
Zolang er gegevens in de stroom zijn

Lees gegevens in de buffer
Schrijf de gegevens van de buffer naar de tweede stroom

2. Writerklasse

De Writerklasse is precies hetzelfde als de OutputStreamklasse, maar er is weer één verschil: het werkt met tekens ( char) in plaats van met bytes.

Dit is een abstracte klasse: u kunt geen objecten van de Writerklasse maken. Het belangrijkste doel is om een ​​gemeenschappelijke ouderklasse te zijn voor honderden onderliggende klassen en hen gemeenschappelijke methoden te geven voor het werken met personagestromen.

Methoden van de Writerklasse (en al zijn onderliggende klassen):

methoden Beschrijving
void write(int b)
Schrijft één teken (geen int) naar de stream.
void write(char[] buffer)
Schrijft een reeks tekens naar de stream
void write(char[] buffer, off, len)
Schrijft een deel van een reeks tekens naar de stream
void write(String str)
Schrijft een string naar de stream
void write(String str, off, len)
Schrijft een deel van een string naar de stream
void flush()
Schrijft alle gegevens die in de buffer zijn opgeslagen naar de stream
void close()
Sluit de stroom af

De methoden lijken sterk op de methoden van de OutputStreamklasse, maar ze werken met tekens in plaats van bytes.

Beschrijving van methoden:

write(int b)methode

Deze methode schrijft een enkel teken ( char— niet een int) naar de uitvoerstroom. De doorgegeven waarde wordt gecast naar a charen de eerste twee bytes worden weggegooid.

write(char[] buffer)methode

Schrijft de gegeven reeks tekens naar de uitvoerstroom.

write(char[] buffer, int offset, int length)methode

Schrijft een deel van de doorgegeven reeks tekens naar de uitvoerstroom. De offsetvariabele geeft de index aan van het eerste element van de array en lengthis de lengte van de te schrijven subset.

write(String str)methode

Schrijft de gegeven string naar de uitvoerstroom.

write(String str, int offset, int length)methode

Schrijft een deel van de gegeven tekenreeks naar de uitvoerstroom: de tekenreeks wordt geconverteerd naar een reeks tekens. De offsetvariabele geeft de index aan van het eerste element van de array en lengthis de lengte van de te schrijven subset.

flush()methode

De flush()methode wordt gebruikt om alle potentieel gebufferde gegevens in de huidige stroom te forceren om naar de doelstroom te schrijven. Dit is relevant bij het gebruik van buffering en/of meerdere stream-objecten die in een keten zijn gerangschikt.

close()methode

Schrijft alle ongeschreven gegevens naar het doelobject. De close()methode hoeft niet te worden aangeroepen als u een try-with-resourcesblok gebruikt.

Voorbeeld van een programma dat een tekstbestand kopieert:

Code Opmerking
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);
   }
}



Readervoor het lezen van een bestand
Writervoor het schrijven naar een bestand

Buffer waarin we de gegevens zullen lezen
Zolang er gegevens in de stroom zijn

Lees gegevens in een buffer
Schrijf de gegevens van de buffer naar de tweede stroom

StringWriterklas

Er is nog een andere interessante klasse die de Writerklasse erft: deze heet StringWriter. Het bevat een veranderlijke string - een StringBufferobject. En elke keer dat u iets naar het StringWriterobject "schrijft", wordt de tekst gewoon toegevoegd aan de interne buffer.

Voorbeeld:

Code Opmerking
StringWriter writer = new StringWriter();
writer.write("Hello");
writer.write(String.valueOf(123));

String result = writer.toString();
Er wordt een doeltekenstroom ( StringWriter) gemaakt
Er wordt een tekenreeks naar de buffer in de buffer geschreven StringWriter
Een tekenreeks wordt naar de buffer in de StringWriter

De inhoud van een object in een tekenreeks converteren

In dit geval is de StringWriterklasse in wezen een wikkel over de StringBufferklasse, maar de StringWriterklasse is een afstammeling van de Writerstroomklasse en kan worden gebruikt in ketens van stroomobjecten. Dit is in de praktijk een behoorlijk nuttige eigenschap.



3. PrintStreamklasse

Uitvoerstroomklassen kunnen ook in een keten worden geplaatst met tussenstromen die gegevens schrijven naar de doelstroom die aan hen wordt doorgegeven. Het algemene beeld van de interactie van deze stromen ziet er als volgt uit:

PrintStream-klasse

De meest interessante en veelzijdige van alle tussenliggende outputstromen is PrintStream. Het heeft tientallen methoden en maar liefst 12 constructors.

De PrintStreamklasse erft de FilterOutputStreamklasse, die erft OutputStream. Dat betekent dat de klasse naast zijn eigen methoden alle methoden van de bovenliggende klassenPrintStream heeft . Dit zijn de meest interessante:

methoden Beschrijving
void print(obj)
Converteert het doorgegeven object naar een tekenreeks en voert het uit naar de doelstroom.
void println(obj)
Converteert het doorgegeven object naar een tekenreeks en voert het uit naar de doelstroom. Voegt een regeleinde toe aan het einde
void println()
Voert een regeleinde-teken uit naar de doelstroom
PrintStream format(String format, args...)
Construeert en voert een tekenreeks uit op basis van de opmaaktekenreeks en de doorgegeven argumenten; vergelijkbaar met de String.format()methode

En waar zijn deze tientallen methoden, vraag je?

Nou, het heeft veel varianten van de methoden print()en println()met verschillende parameters. Ze kunnen in deze tabel worden samengevat.

Op deze methodes gaan we niet in, omdat je ze al goed kent. Kun je raden waar ik op doel?

Weet je nog System.out.println()? Maar het kan in twee regels worden geschreven:

Code Console-uitvoer
PrintStream stream = System.out;
stream.println("Hello!");
Hello!

Ons favoriete commando is een aanroep van de methode op de statische variabele van de klasse. En het type van deze variabele is .System.out.println()println()outSystemPrintStream

In veel CodeGym-niveaus, en in bijna elke taak, heb je methoden van de PrintStreamklas genoemd zonder het te weten!

Praktisch gebruik

Java heeft deze interessante klasse genaamd ByteArrayOutputStream, wat een dynamisch groeiende byte-array is die overerft OutputStream.

Een ByteArrayOutputStreamobject en PrintStreamobject kunnen als volgt worden geketend:

Code Beschrijving
ByteArrayOutputStream baos = new ByteArrayOutputStream();

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

String result = baos.toString();

System.out.println(result);
Creëer een schrijfbuffer in het geheugen

Wikkel de buffer in een PrintStreamobject

Schrijf data naar de console



Converteer de array naar een string!

Console-uitvoer:
Hello!
123