Vejledning til Java OutputStream

1. Oversigt

I denne vejledning udforsker vi detaljer om Java-klassen OutputStream. OudputStream er en abstrakt klasse. Dette tjener som superklassen for alle klasser, der repræsenterer en outputstrøm af bytes.

Vi undersøger, hvad disse ord som "output" og "stream" betyder i flere detaljer, når vi går videre.

2. Kort introduktion til Java IO

OutputStream er en del af Java IO API der definerer klasser, der kræves for at udføre I / O-operationer i Java. Disse er alle pakket i java.io navneområde. Dette er en af ​​de kernepakker, der er tilgængelige i Java siden version 1.0.

Ved at starte Java 1.4 har vi også Java NIO pakket i navneområdet java.nio som muliggør ikke-blokerende input- og outputoperationer. Vores fokusområde for denne artikel er dog ObjectStream som en del af Java IO.

Detaljer relateret til Java IO og Java NIO kan findes her.

2.1. Indgang og udgang

Java IO giver dybest set en mekanisme til at læse data fra en kilde og skrive data til en destination. Input repræsenterer kilden, mens output repræsenterer destinationen her.

Disse kilder og destinationer kan være alt fra filer, rør til netværksforbindelser.

2.2. Strømme

Java IO giver begrebet streams, som grundlæggende repræsenterer en kontinuerlig strøm af data. Streams kan understøtte mange forskellige typer data som bytes, tegn, objekter osv.

Desuden er forbindelse til en kilde eller en destination, hvad en strøm repræsenterer. De kommer derfor som begge InputStream eller OutputStream henholdsvis.

3. Grænseflader til OutputStream

OutputStream implementerer en masse grænseflader, som giver en del tydelig karakter til dens underklasser. Lad os gå igennem dem hurtigt.

3.1. Kan lukkes

Grænsefladen Kan lukkes giver en metode kaldet tæt() hvilken håndterer lukning af en kilde eller en destination for data. Hver implementering af OutputStream skal give en implementering af denne metode. Her kan de udføre handlinger for at frigøre ressourcer.

3.2. Kan lukkes automatisk

Grænsefladen Kan lukkes automatisk giver også en metode kaldet tæt() med lignende adfærd som den i Kan lukkes. I dette tilfælde er imidlertid metode tæt() kaldes automatisk, når du afslutter en prøve-med-ressource-blok.

Flere detaljer vedrørende prøv-med-ressource kan findes her.

3.3. Kan skylles

Grænsefladen Kan skylles giver en metode kaldet Flush() der håndterer skylningsdata til en destination.

En særlig implementering af OutputStream kan vælge at buffer tidligere skrevne bytes for at optimere, men et opkald til Flush() får det til at skrive til destinationen med det samme.

4. Metoder i OutputStream

OutputStream har flere metoder, som hver implementeringsklasse skal implementere for deres respektive datatyper.

Disse er bortset fra tæt() og Flush() metoder, som den arver fra Kan lukkes og Kan skylles grænseflader.

4.1. skriv (int b)

Vi kan bruge denne metode til at skriv en bestemt byte til OutputStream. Da argumentet “int” omfatter fire byte, som par kontrakten skrives kun den første lavordensbyte og de resterende tre højordensbyte og ignoreres:

offentlig statisk ugyldig filOutputStreamByteSingle (strengfil, strengdata) kaster IOException {byte [] bytes = data.getBytes (); prøv (OutputStream out = ny FileOutputStream (fil)) {out.write (bytes [6]); }}

Hvis vi kalder denne metode med data som “Hello World!”, Får vi som resultat en fil med følgende tekst:

W

Dette er, som vi kan se, det syvende tegn i den streng, der er indekseret sjette.

4.2. skriv (byte [] b, int off, int længde)

Denne overbelastede version af skrive() metoden er der for skriv en undersekvens af byte array til OutputStream.

Det kan skrive "længde" antal bytes fra byte-arrayet som specificeret af argumentet startende ved en forskydning bestemt af "off" til OutputStream:

offentlig statisk ugyldig filOutputStreamByteSubSequence (strengfil, strengdata) kaster IOException {byte [] bytes = data.getBytes (); prøv (OutputStream out = ny FileOutputStream (fil)) {out.write (bytes, 6, 5); }}

Hvis vi nu kalder denne metode med de samme data som før, får vi følgende tekst i vores outputfil:

Verden

Dette er undergrunden for vores data, der starter ved indeks fem og består af fem tegn.

4.3. skriv (byte [] b)

Dette er endnu en overbelastet version af skrive() metode, som kan skriv et helt byte-array som specificeret af argumentet til OutputStream.

Dette har den samme effekt som et kald til skriv (b, 0, b.lengh):

offentlig statisk ugyldig filOutputStreamByteSequence (strengfil, strengdata) kaster IOException {byte [] bytes = data.getBytes (); prøv (OutputStream out = ny FileOutputStream (fil)) {out.write (bytes); }}

Når vi nu kalder denne metode med de samme data, har vi det hele Snor i vores outputfil:

Hej Verden!

5. Direkte underklasser af OutputStream

Nu diskuterer vi nogle af de direkte kendte underklasser af OutputStream som hver for sig repræsenterer en specifik datatype, hvoraf OutputStream definerer de.

De definerer deres egne metoder bortset fra at implementere dem, der er arvet fra OutputStream.

Vi går ikke nærmere ind på detaljerne i disse underklasser.

5.1. FileOutputStream

Som navnet antyder, a FileOutputStream er en OutputStream at skrive data til en Fil. FileOutputStreamsom alle andre OutputStream, kan skrive en strøm af rå byte.

Vi har allerede undersøgt forskellige metoder i FileOutputStream som en del af det sidste afsnit.

5.2. ByteArrayOutputStream

ByteArrayOutputStream er en gennemførelse af OutputStream der kan skrive data i et byte-array. Bufferen fortsætter med at vokse som ByteArrayOutputStream skriver data til det.

Vi kan beholde den oprindelige standardstørrelse af bufferen som 32 byte eller indstille en bestemt størrelse ved hjælp af en af ​​de tilgængelige konstruktører.

Den vigtige ting at bemærke her er, at metoden tæt() har praktisk talt ingen effekt. De andre metoder i ByteArrayOutputStream kan kaldes sikkert selv efter tæt() er blevet kaldt.

5.3. FilterOutputStream

OutputStream skriver primært en byte-stream til en destination, men det kan lige så godt transformere dataene, inden de gør det. FilterOutputStream repræsenterer superklasse af alle sådanne klasser, der udfører en specifik datatransformation. FilterOutputStream er altid konstrueret med en eksisterende OutputStream.

Nogle af eksemplerne på FilterOutputStream er BufferedOutputStream, CheckedOutputStream, CipherOutputStream, DataOutputStream, DeflaterOutputStream, DigestOutputStream, InflaterOutputStream, PrintStream.

5.4. ObjectOutputStream

ObjectOutputStream kan skriv primitive datatyper og grafer over Java-objekter til en destination. Vi kan konstruere en ObjectOutputStream ved hjælp af en eksisterende OutputStream at skrive til en bestemt destination som File.

Bemærk, at det er nødvendigt, at objekter implementeres Serialiserbar til ObjectOutputStream at skrive dem til en destination. Du kan finde flere detaljer om Java Serialization her.

5.5. PipedOutputStream

EN PipedOutputStream er nyttigt at oprette et kommunikationsrør. PipedOutputStream kan skrive data, som en tilsluttet PipedInputStream kan læse.

PipedOutputStream har en konstruktør til at forbinde den med en PipedInputStream. Alternativt kan vi gøre dette senere ved at bruge en metode, der er angivet i PipedOutputStream hedder Opret forbindelse().

6. OutputStream Buffering

Input- og outputoperationer involverer typisk relativt dyre operationer som diskadgang, netværksaktivitet osv. At udføre dette ofte kan gøre et program mindre effektivt.

Vi har "bufferede strømme" af data i Java til at håndtere disse scenarier. BufferedOutputStreamskriver data til en buffer i stedet, som skylles til destinationen sjældnere, når bufferen bliver fuld, eller metoden Flush() Hedder.

BufferedOutputStream strækker sig FilterOutputStream diskuteret tidligere og indpakker en eksisterende OutputStream at skrive til en destination:

offentlig statisk ugyldig bufferedOutputStream (strengfil, streng ... data) kaster IOException {try (BufferedOutputStream out = new BufferedOutputStream (new FileOutputStream (file))) {for (String s: data) {out.write (s.getBytes () ); out.write ("" .getBytes ()); }}}

Det kritiske punkt at bemærke er, at hvert opkald til skrive() for hvert dataargument skriver kun til bufferen og resulterer ikke i et potentielt dyrt opkald til filen.

I ovenstående tilfælde, hvis vi kalder denne metode med data som "Hej", "Verden!", Vil dette kun resultere i, at data skrives til filen, når koden kommer ud af den prøve-med-ressource-blok, der kalder metoden tæt() på den BufferedOutputStream.

Dette resulterer i en outputfil med følgende tekst:

Hej Verden!

7. Skrivning af tekst med OutputStreamWriter

En byte stream, som diskuteret tidligere, repræsenterer rådata, der kan være en flok teksttegn. Nu kan vi hente tegnarrayet og udføre konverteringen til byte-arrayet selv:

byte [] bytes = data.getBytes ();

Java giver praktiske klasser til at bygge bro over dette hul. For sagen om OutputStream, denne klasse er OutputStreamWriter. OutputStreamWriter indpakker en OutputStream og kan skrive tegn direkte til den ønskede destination.

Vi kan også valgfrit levere OutputStreamWriter med et tegnsæt til kodning:

offentlig statisk ugyldig outputStreamWriter (strengfil, strengdata) kaster IOException {prøv (OutputStream ud = ny FileOutputStream (fil); Forfatterforfatter = ny OutputStreamWriter (ud, "UTF-8")) {writer.write (data); }}

Nu som vi kan se, behøver vi ikke udføre transformationen af ​​tegnarrayet til byte-arrayet, før vi bruger det FileOutputStream.OutputStreamWriter gør dette bekvemt for os.

Ikke overraskende, når vi kalder ovenstående metode med data som "Hello World!", Resulterer dette i en fil med tekst som:

Hej Verden!

8. Konklusion

I denne artikel diskuterede vi Java-abstraktklassen OutputStream. Vi gennemgik de grænseflader, den implementerer, og de metoder, den giver.

Derefter diskuterede vi nogle af underklasserne i OutputStream tilgængelig i Java. Vi talte endelig om buffering og karakterstrømme.

Som altid er koden til eksemplerne tilgængelig på GitHub.