Vodič za Java OutputStream

1. Pregled

U ovom uputstvu istražit ćemo detalje o klasi Java Izlazni tok. OutputStream je apstraktna klasa. Ovo služi kao superklasa za sve klase koja predstavlja izlazni tok bajtova.

Ispitati ćemo što više znače ove riječi poput "izlaz" i "tok", dok idemo dalje.

2. Kratki uvod u Java IO

OutputStream je dio Java IO API-ja koja definira klase potrebne za izvođenje I / O operacija na Javi. Sve je to zapakirano u java.io prostor imena. Ovo je jedan od osnovnih paketa dostupnih u Javi od verzije 1.0.

Počevši od Jave 1.4, u prostoru imena imamo i Java NIO java.nio što omogućuje neblokiranje ulaznih i izlaznih operacija. Međutim, naše fokusno područje za ovaj članak je ObjectStream kao dio Java IO-a.

Pojedinosti povezane s Java IO i Java NIO možete pronaći ovdje.

2.1. Ulaz i izlaz

Java IO u osnovi pruža mehanizam za čitanje podataka iz izvora i zapisivanje podataka na odredište. Ulaz predstavlja izvor, dok izlaz ovdje predstavlja odredište.

Ti izvori i odredišta mogu biti bilo što, od datoteka, cijevi do mrežnih veza.

2.2. Potoci

Java IO pruža koncept tokovi koji u osnovi predstavljaju kontinuirani protok podataka. Potoci mogu podržavati mnogo različitih vrsta podataka poput bajtova, znakova, objekata itd.

Štoviše, veza s izvorom ili odredištem ono je što tok predstavlja. Stoga dolaze kao bilo koji InputStream ili Izlazni tok odnosno.

3. Sučelja Izlazni tok

Izlazni tok implementira hrpu sučelja koja svojim podrazredima daju neki različit karakter. Krenimo brzo kroz njih.

3.1. Može se zatvoriti

Sučelje Može se zatvoriti pruža metodu koja se naziva Zatvoriti() koji rukuje zatvaranjem izvora ili odredišta podataka. Svaka primjena Izlazni tok mora osigurati provedbu ove metode. Ovdje mogu izvoditi radnje za oslobađanje resursa.

3.2. AutoCloseable

Sučelje AutoCloseable također pruža metodu tzv Zatvoriti() sa sličnim ponašanjem kao u Može se zatvoriti. U ovom slučaju, međutim, metoda Zatvoriti() automatski se poziva prilikom izlaska iz bloka try-with-resource.

Više detalja o pokušaju s resursom možete pronaći ovdje.

3.3. Ispirati

Sučelje Ispirati pruža metodu koja se naziva isprati () koji obrađuje ispiranje podataka do odredišta.

Posebna provedba Izlazni tok može odlučiti za međuspremnik prethodno napisanih bajtova radi optimizacije, ali poziv na isprati () natjera ga da odmah napiše na odredište.

4. Metode u OutputStream-u

Izlazni tok ima nekoliko metoda koje svaka izvedbena klasa mora implementirati za svoje odgovarajuće tipove podataka.

Ovo su osim Zatvoriti() i isprati () metode od kojih nasljeđuje Može se zatvoriti i Ispirati sučelja.

4.1. napiši (int b)

Ovu metodu možemo koristiti za napiši jedan određeni bajt u Izlazni tok. Budući da se argument "int" sastoji od četiri bajta, kao što je navedeno u ugovoru, zapisuje se samo prvi bajt niskog reda, a preostala tri bajta visokog reda ignoriraju se:

javna statička void fileOutputStreamByteSingle (datoteka niza, niz podataka) baca IOException {byte [] bytes = data.getBytes (); probajte (OutputStream out = novi FileOutputStream (datoteka)) {out.write (bajtovi [6]); }}

Ako ovu metodu s podacima nazivamo "Hello World!", Kao rezultat dobivamo datoteku sa sljedećim tekstom:

W

Ovo je, kao što vidimo, sedmi znak indeksiranog šestog niza.

4.2. zapis (bajt [] b, int isključeno, dužina int)

Ova preopterećena verzija pisati() metoda je tu da zapisati pod-niz bajt polja u Izlazni tok.

Može zapisati "duljinu" broja bajtova iz bajt polja, kako je navedeno argumentom, počevši od pomaka određenog s "off" na Izlazni tok:

javna statička void fileOutputStreamByteSubSequence (datoteka niza, niz podataka) baca IOException {byte [] bytes = data.getBytes (); probajte (OutputStream out = novi FileOutputStream (datoteka)) {out.write (bajtovi, 6, 5); }}

Ako ovu metodu sada pozovemo s istim podacima kao i prije, u našoj izlaznoj datoteci dobit ćemo sljedeći tekst:

Svijet

Ovo je podniz naših podataka koji započinju s indeksom pet i sadrže pet znakova.

4.3. zapis (bajt [] b)

Ovo je još jedna preopterećena verzija pisati() metoda koja može zapisati čitav niz bajtova kako je navedeno argumentom Izlazni tok.

To ima isti učinak kao i poziv na napiši (b, 0, b.dugo):

javna statička void fileOutputStreamByteSequence (datoteka niza, podaci niza) baca IOException {byte [] bytes = data.getBytes (); probajte (OutputStream out = novi FileOutputStream (datoteka)) {out.write (bajtovi); }}

Kada ovu metodu zovemo sada s istim podacima, imamo cjelovitu Niz u našoj izlaznoj datoteci:

Pozdrav svijete!

5. Izravne podrazrede Izlazni tok

Sada ćemo razgovarati o nekim izravno poznatim podrazredima Izlazni tok koji pojedinačno predstavljaju određenu vrstu podataka od kojih Izlazni tok definiraju.

Oni definiraju vlastite metode, osim provedbe onih naslijeđenih od Izlazni tok.

Nećemo ulaziti u detalje ovih podrazreda.

5.1. FileOutputStream

Kao što i samo ime govori, a FileOutputStream je an Izlazni tok za upisivanje podataka u a Datoteka. FileOutputStream, kao i bilo koji drugi Izlazni tok, može napisati tok neobrađenih bajtova.

Već smo ispitivali različite metode u FileOutputStream kao dio posljednjeg odjeljka.

5.2. ByteArrayOutputStream

ByteArrayOutputStream je provedba Izlazni tok koji mogu upisivati ​​podatke u bajtni niz. Međuspremnik nastavlja rasti kao ByteArrayOutputStream upisuje podatke u nju.

Možemo zadržati zadanu početnu veličinu međuspremnika kao 32 bajta ili postaviti određenu veličinu pomoću jednog od dostupnih konstruktora.

Ovdje je važno napomenuti da je metoda Zatvoriti() praktički nema učinka. Ostale metode u ByteArrayOutputStream može se sigurno nazvati i nakon Zatvoriti() je pozvan.

5.3. FilterOutputStream

OutputStream prvenstveno upisuje tok bajtova na odredište, ali može i transformirati podatke prije nego što to učini. FilterOutputStream predstavlja superklasa svih takvih klasa koje izvode specifičnu transformaciju podataka. FilterOutputStream uvijek se gradi s postojećim Izlazni tok.

Neki od primjera FilterOutputStream jesu BufferedOutputStream, Provjereni izlazni tok, CipherOutputStream, DataOutputStream, DeflaterOutputStream, DigestOutputStream, InflaterOutputStream, PrintStream.

5.4. ObjectOutputStream

ObjectOutputStream limenka pisati primitivne tipove podataka i grafikone Java objekata do odredišta. Možemo konstruirati ObjectOutputStream koristeći postojeću Izlazni tok za pisanje na određeno odredište poput File.

Imajte na umu da je potrebno objekte implementirati Serijalizirati za ObjectOutputStream da ih napišem na odredište. Više detalja o Java serializaciji možete pronaći ovdje.

5.5. PipedOutputStream

A PipedOutputStream je korisno za stvaranje komunikacijske cijevi. PipedOutputStream može pisati podatke koji povezani PipedInputStream zna čitati.

PipedOutputStream sadrži konstruktor za povezivanje s a PipedInputStream. To možemo učiniti i kasnije uporabom metode predviđene u PipedOutputStream pozvao Spojiti().

6. Izlazni tok Međuspremnik

Ulazne i izlazne operacije obično uključuju relativno skupe operacije poput pristupa disku, mrežne aktivnosti itd. Izvođenjem toga često program može biti manje učinkovit.

Imamo "baferirane tokove" podataka na Javi za obradu ovih scenarija. BufferedOutputStreamumjesto toga zapisuje podatke u međuspremnik koji se rjeđe uklanja na odredište, kada se me uspremnik napuni, ili metoda isprati () Zove se.

BufferedOutputStream proteže se FilterOutputStream o čemu smo ranije razgovarali i obavija postojeće Izlazni tok za pisanje na odredište:

javna statička void bufferedOutputStream (datoteka niza, niz ... podaci) baca IOException {try (BufferedOutputStream out = new BufferedOutputStream (new FileOutputStream (file))) {for (String s: data) {out.write (s.getBytes () ); out.write ("" .getBytes ()); }}}

Kritično je napomenuti da svaki poziv na pisati() za svaki argument podataka zapisuje samo u međuspremnik i ne rezultira potencijalno skupim pozivom datoteke.

U gornjem slučaju, ako ovu metodu s podacima nazivamo „Zdravo”, „Svijet!”, To će rezultirati zapisom podataka u datoteku samo kada kod izađe iz bloka try-with-resources koji poziva metodu Zatvoriti() na BufferedOutputStream.

To rezultira izlaznom datotekom sa sljedećim tekstom:

Pozdrav svijete!

7. Pisanje teksta sa OutputStreamWriter

Struja bajtova, kao što je prethodno rečeno, predstavlja sirove podatke koji mogu biti hrpa tekstualnih znakova. Sada možemo dobiti niz znakova i sami izvršiti pretvorbu u bajtni niz:

bajt [] bajtova = data.getBytes ();

Java nudi prikladne klase kako bi premostila ovaj jaz. Za slučaj Izlazni tok, ovaj razred je OutputStreamWriter. OutputStreamWriter obavija an Izlazni tok i mogu izravno pisati znakove na željeno odredište.

Po želji možemo pružiti i OutputStreamWriter sa skupom znakova za kodiranje:

javna statička praznina outputStreamWriter (datoteka niza, podaci niza) baca IOException {try (OutputStream out = new FileOutputStream (datoteka); Writer Writer = new OutputStreamWriter (out, "UTF-8")) {writer.write (podaci); }}

Sada, kao što vidimo, ne moramo izvršiti transformaciju niza znakova u bajtni niz prije upotrebe FileOutputStream.OutputStreamWriter to čini prikladno za nas.

Nije iznenađujuće kada gornju metodu pozovemo s podacima poput "Hello World!", To rezultira datotekom s tekstom kao:

Pozdrav svijete!

8. Zaključak

U ovom smo članku raspravljali o apstraktnoj klasi Java Izlazni tok. Prošli smo kroz sučelja koja implementira i metode koje pruža.

Zatim smo razgovarali o nekim podrazredima Izlazni tok dostupno na Javi. Napokon smo razgovarali o međuspremnicima i strujanju znakova.

Kao i uvijek, kod za primjere dostupan je na GitHub-u.