Sprievodca po BufferedReader

1. Prehľad

BufferedReader je trieda, ktorá zjednodušuje čítanie textu zo vstupného toku znakov. Znaky ukladá do medzipamäte, aby bolo možné efektívne čítať textové údaje.

V tomto výučbe sa pozrieme na to, ako používať BufferedReader trieda.

2. Kedy použiť BufferedReader

Všeobecne, BufferedReader príde vhod, ak chceme čítať text z akéhokoľvek druhu vstupného zdroja, či už sú to súbory, zásuvky alebo niečo iné.

Jednoducho povedané, umožňuje nám to minimalizovať počet I / O operácií čítaním blokov znakov a ich ukladaním do internej medzipamäte. Zatiaľ čo vyrovnávacia pamäť obsahuje údaje, čítačka bude čítať z nej namiesto priamo z podkladového toku.

2.1. Ukladanie do vyrovnávacej pamäte iného čitateľa

Rovnako ako väčšina tried I / O Java,BufferedReader náradie Dekoratérsky vzor, čo znamená, že očakáva Čitateľ v jeho konštruktore. Týmto spôsobom nám umožňuje flexibilne rozšíriť inštanciu a Čitateľ implementácia s funkciou vyrovnávacej pamäte:

Čítačka BufferedReader = nový BufferedReader (nový FileReader ("src / main / resources / input.txt"));

Ak nám však nezáleží na ukladaní do vyrovnávacej pamäte, mohli by sme použiť iba a FileReader priamo:

Čítačka FileReader = nový FileReader ("src / main / resources / input.txt");

Okrem ukladania do vyrovnávacej pamäte BufferedReader tiež poskytuje niekoľko príjemných pomocných funkcií na čítanie súborov riadok po riadku. Takže aj keď sa to môže javiť jednoduchšie FileReader priamo, BufferedReader môže byť veľkou pomocou.

2.2. Ukladanie do vyrovnávacej pamäte prúdu

Všeobecne, môžeme nakonfigurovať BufferedReader prijať akýkoľvek druh vstupného tokuako podkladový zdroj. Môžeme to urobiť pomocou InputStreamReader a zabalím ho do konštruktora:

Čítačka BufferedReader = nový BufferedReader (nový InputStreamReader (System.in));

Vo vyššie uvedenom príklade čítame z System.in čo obvykle zodpovedá vstupu z klávesnice. Podobne by sme mohli odovzdať vstupný prúd na čítanie zo soketu, súboru alebo z iného predstaviteľného typu textového vstupu. Jediným predpokladom je, že existuje vhodný InputStream implementáciu.

2.3. BufferedReader vs Scanner

Ako alternatívu by sme mohli použiť Skener triedy dosiahnuť rovnakú funkcionalitu ako s BufferedReader.

Medzi týmito dvoma triedami však existujú značné rozdiely, vďaka ktorým sú pre nás viac alebo menej vhodné v závislosti od nášho prípadu použitia:

  • BufferedReader je synchronizovaný (bezpečný pre vlákna), zatiaľ čo skener nie
  • Skener dokáže analyzovať primitívne typy a reťazce pomocou regulárnych výrazov
  • BufferedReader umožňuje meniť veľkosť medzipamäte, zatiaľ čo skener má pevnú veľkosť medzipamäte
  • BufferedReader má väčšiu predvolenú veľkosť vyrovnávacej pamäte
  • Skener skrýva sa Výnimka IO, zatiaľ čo BufferedReader núti nás to zvládnuť
  • BufferedReader je zvyčajne rýchlejší ako Skener pretože číta iba údaje bez ich analýzy

Majúc na pamäti tieto ak analyzujeme jednotlivé tokeny v súbore, potom Skener sa bude cítiť o niečo prirodzenejší ako BufferedReader. Lenže práve čítanie riadkov je miesto, kde BufferedReader svieti.

V prípade potreby máme tiež sprievodcu Skener tiež.

3. Čítanie textu pomocou BufferedReader

Poďme si prejsť celým procesom stavby, používania a zničenia a BufferReader správne čítať z textového súboru.

3.1. Inicializuje sa a BufferedReader

Po prvé, vytvorme a BufferedReader pomocou jeho BufferedReader (čítačka) konštruktér:

Čítačka BufferedReader = nový BufferedReader (nový FileReader ("src / main / resources / input.txt"));

Balenie FileReader takto je to pekný spôsob, ako pridať ukladanie do vyrovnávacej pamäte ako aspekt pre ostatných čitateľov.

Predvolene sa použije vyrovnávacia pamäť 8 KB. Ak však chceme ukladať do vyrovnávacích pamätí menšie alebo väčšie bloky, môžeme použiť BufferedReader (Reader, int) konštruktér:

Čítačka BufferedReader = nový BufferedReader (nový FileReader ("src / main / resources / input.txt")), 16384);

Týmto sa nastaví veľkosť medzipamäte na 16384 bajtov (16 KB).

Optimálna veľkosť vyrovnávacej pamäte závisí od faktorov, ako je typ vstupného toku a hardvér, na ktorom je spustený kód. Z tohto dôvodu, aby sme dosiahli ideálnu veľkosť medzipamäte, musíme si ju sami nájsť experimentovaním.

Najlepšie je použiť ako veľkosť vyrovnávacej pamäte mocniny 2, pretože väčšina hardvérových zariadení má ako veľkosť bloku silu 2.

Nakoniec existuje ešte jeden šikovný spôsob, ako vytvoriť BufferedReader pomocou Súbory pomocná trieda z java.nioAPI:

Čítačka BufferedReader = Files.newBufferedReader (Paths.get ("src / main / resources / input.txt"))

Vytvára sa totakto je to pekný spôsob medzipamäte, ak chceme načítať súbor, pretože nemusíme ručne vytvárať a FileReader najskôr a potom zabaliť.

3.2. Čítanie riadok po riadku

Ďalej si prečítajme obsah súboru pomocou readLine metóda:

public String readAllLines (čítačka BufferedReader) vyvolá IOException {StringBuilder content = new StringBuilder (); Šnúrka; while ((line = reader.readLine ())! = null) {content.append (line); content.append (System.lineSeparator ()); } návrat content.toString (); }

Rovnakým spôsobom ako hore môžeme urobiť pomocou riadky metóda zavedená v prostredí Java 8 o niečo jednoduchšie:

public String readAllLinesWithStream (čítačka BufferedReader) {návrat reader.lines () .collect (Collectors.joining (System.lineSeparator ())); }

3.3. Uzatváranie streamu

Po použití BufferedReader, musíme to nazvať Zavrieť() metóda na uvoľnenie akýchkoľvek systémových prostriedkov s tým spojených. Toto sa deje automaticky, ak použijeme a vyskúšajte zdroje blok:

try (čítačka BufferedReader = nový BufferedReader (nový FileReader ("src / main / resources / input.txt")))) {return readAllLines (reader); }

4. Ďalšie užitočné metódy

Teraz sa zamerajme na rôzne užitočné metódy dostupné v BufferedReader.

4.1. Čítanie jedného znaku

Môžeme použiť čítať() metóda na čítanie jedného znaku. Poďme si prečítať celý obsah po znakoch až do konca streamu:

public String readAllCharsOneByOne (čítačka BufferedReader) hodí IOException {StringBuilder content = new StringBuilder (); hodnota int; while ((value = reader.read ())! = -1) {content.append ((char) hodnota); } návrat content.toString (); }

Toto načíta znaky (vrátené ako hodnoty ASCII), vrhne ich na char a pripojiť ich k výsledku. Toto opakujeme až do konca toku, čo je indikované hodnotou odozvy -1 z čítať() metóda.

4.2. Čítanie viacerých znakov

Ak chceme čítať viac znakov naraz, môžeme použiť metódu read (char [] cbuf, int off, int len):

public String readMultipleChars (čítačka BufferedReader) hodí IOException {int dĺžka; char [] chars = nový char [dĺžka]; int charsRead = reader.read (znaky, 0, dĺžka); Výsledok reťazca; if (charsRead! = -1) {result = new String (chars, 0, charsRead); } else {vysledok = ""; } vrátiť výsledok; }

V uvedenom príklade kódu prečítame až 5 znakov do poľa char a z neho zostavíme reťazec. V prípade, že sme pri našom pokuse o čítanie nečítali žiadne znaky (t. J. Dosiahli sme koniec streamu), jednoducho vrátime prázdny reťazec.

4.3. Preskakovanie znakov

Zadaný počet znakov môžeme tiež preskočiť volaním znaku preskočiť (dlhé n) metóda:

@Test public void givenBufferedReader_whensSkipChars_thenOk () vyvolá IOException {výsledok StringBuilder = nový StringBuilder (); try (čítačka BufferedReader = nový BufferedReader (nový StringReader ("1__2__3__4__5")))) {int hodnota; while ((value = reader.read ())! = -1) {result.append ((char) value); reader.skip (2L); }} assertEquals ("12345", výsledok); }

Vo vyššie uvedenom príklade čítame zo vstupného reťazca, ktorý obsahuje čísla oddelené dvoma podčiarknutiami. Aby sme vytvorili reťazec obsahujúci iba čísla, preskočíme podčiarknutia volaním preskočiť metóda.

4.4. známka a resetovať

Môžeme použiť značka (int readAheadLimit) a reset () metódy označiť určitú pozíciu v streame a vrátiť sa k nej neskôr. Ako trochu vymyslený príklad použijeme značka () a reset () ignorovať všetky medzery na začiatku streamu:

@Test public void givenBufferedReader_whenSkipsWhitespacesAtBeginning_thenOk () vyvolá IOException {výsledok reťazca; try (BufferedReader reader = new BufferedReader (new StringReader ("Lorem ipsum dolor sit amet."))) {do {reader.mark (1); } while (Character.isWhitespace (reader.read ())) reader.reset (); výsledok = reader.readLine (); } assertEquals ("Lorem ipsum dolor sit amet.", výsledok); }

Vo vyššie uvedenom príklade používame značka () metóda na označenie polohy, ktorú sme práve čítali. Ak jej dáte hodnotu 1, znamená to, že iba kód si zapamätá značku o jeden znak vpred. Je to tu užitočné, pretože akonáhle uvidíme náš prvý znak bez medzier, môžeme sa vrátiť späť a znovu ho prečítať bez toho, aby sme museli znova spracovať celý stream. Bez známky by sme stratili Ľ v našom poslednom reťazci.

Všimnite si, že preto značka () môže hodiť UnsupportedOperationException, je dosť bežné združovať sa markSupported () s kódom, ktorý vyvolá známka(). Tu to však vlastne nepotrebujeme. To je preto, lebo markSupported () vždy vráti true pre BufferedReader.

Samozrejme, vyššie uvedené by sme mohli urobiť trochu elegantnejšie inými spôsobmi, a skutočne známka a resetovať nie sú veľmi typické metódy. Určite však prídu vhod, keď je potrebné pozerať sa dopredu.

5. Záver

V tejto rýchlej príručke sme sa naučili, ako čítať vstupné toky znakov na praktickom príklade BufferedReader.

Nakoniec je zdrojový kód príkladov k dispozícii na stránkach Github.


$config[zx-auto] not found$config[zx-overlay] not found