Java BufferedReader: Tiedoston lukeminen esimerkin avulla

โšก ร„lykรคs yhteenveto

Java BufferedReader lukee tekstiรค syรถtevirrasta puskuroimalla merkkejรค, mikรค tekee rivi riviltรค tiedostojen lukemisesta nopeaa ja yksinkertaista.ping tiedostonlukija sisรคllรค BufferedReader ja vessaping readLine-funktiolla, kunnes se palauttaa null-arvon, tulostaa koko tiedoston.

  • ???? Ydintarkoitus: BufferedReader kรครคrii kaikki kalliiksi luettavat lukutoiminnot sisรคltรคvรคn ohjelman, mikรค vรคhentรครค yksittรคisten lukujen mรครคrรครค pohjana olevaa datavirtaa vasten.
  • ๐Ÿ” Lue silmukka: readLine palauttaa yhden rivin kutsua kohden ja null-arvon tiedoston lopussa, joten while-silmukka kรคy lรคpi koko tiedoston kyseisen tuloksen perusteella.
  • ๐Ÿงฑ Pakopolut: A Windows polku sisรคllรค Java merkkijono tarvitsee kaksinkertaisen kenoviivan, muuten kรครคntรคjรค hylkรครค virheellisen ohjausmerkkijonon.
  • โ™ป๏ธ Resurssin julkaisu: Lukijan sulkeminen vapauttaa alla olevan tiedostokahvan; try-with-resources suorittaa tรคmรคn sulkemisen automaattisesti.
  • โŒจ๏ธ Konsolin syรถte: Kรครคriping InputStreamReader-luokassa oleva System.in-tiedosto antaa saman luokan lukea nรคppรคimistรถsyรถtettรค tiedoston sijaan.
  • ๐Ÿ‡ง๐Ÿ‡ท Skannerin kontrasti: BufferedReader on nopeampi ja palauttaa raakarivit, kun taas Scanner jรคsentรครค tokeneita ja alkeistyyppejรค suoraan.
  • ๐Ÿ”ค Merkistรถvaroitus: FileReader kรคyttรครค oletusmerkistรถรค, joten sellaisen mรครคrittรคminen erikseen estรครค merkkien vรครคristymisen eri koneilla.

BufferedReader sisรครคn Java

Kuinka lukea tiedosto sisรครคn Java?

Java tarjoaa useita mekanismeja tiedoston lukemiseen. Hyรถdyllisin paketti tรคhรคn on java.io, jonka vatsalihaksettract Reader luokka mรครคrittelee merkkijonon lukemisen. java.io.BufferedReader on konkreettinen alaluokka, jota kรคytetรครคn tehokkaaseen rivipohjaiseen lukemiseen.

Mikรค on BufferedReader sisรครคn Java?

BufferedReader on Java luokka, joka lukee tekstiรค syรถtevirrasta, kuten tiedostosta, puskuroimalla merkkejรค siten, ettรค merkit, taulukot ja rivit luetaan tehokkaasti. Ilman puskurointia jokainen Readerille tehty lukupyyntรถ laukaisee vastaavan lukupyynnรถn alla olevaa merkki- tai tavuvirtaa vastaan.

Siksi on suositeltavaa kรครคriรค BufferedReader minkรค tahansa Readerin ympรคrillรค, jonka read() operaatiot voivat olla kalliita, esim. FileReader ja InputStreamReaderTyypillinen kรคyttรถtapa vรคlittรครค tiedostopolun lukijalle seuraavasti:

// Note the doubled backslash: a single \ starts an escape sequence
objReader = new BufferedReader(new FileReader("D:\\DukesDiary.txt"));

Tรคmรค lataa tiedoston sisรครคn objReader. Sitten iteroit tiedoston sisรคllรถn lรคpi ja tulostat jokaisen rivin. Alla olevan koodin while-silmukka lukee tiedostoa, kunnes se saavuttaa tiedoston lopun.

while ((strCurrentLine = objReader.readLine()) != null) {
    System.out.println(strCurrentLine);
}

strCurrentLine pitรครค nykyisen linjan ja objReader.readLine() palauttaa merkkijonon. Silmukka siis iteroituu niin kauan kuin palautettu arvo ei ole null, ja pysรคhtyy ensimmรคisen nullin kohdalle, mikรค merkitsee tiedoston loppua.

BufferEsimerkki edReaderistรค

Alla oleva koodi on tรคydellinen Java BufferedReader-esimerkki:

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class ReadFileExample {

    public static void main(String[] args) {
        BufferedReader objReader = null;
        try {
            String strCurrentLine;

            objReader = new BufferedReader(new FileReader("D:\\DukesDiary.txt"));

            while ((strCurrentLine = objReader.readLine()) != null) {
                System.out.println(strCurrentLine);
            }

        } catch (IOException e) {
            e.printStackTrace();

        } finally {
            try {
                if (objReader != null)
                    objReader.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
}

Huomautus: finally lohkolla on merkitystรค. Se takaa, ettรค objReader.close() suoritetaan riippumatta siitรค, heitettiinkรถ poikkeus vai ei, mikรค vapauttaa taustalla olevan tiedostokahvan ja pitรครค Muistinhallinta ennustettavissa. Sisรครคnrakennettu yritys finally on tarpeen, koska close() itse julistaa IOException.

BufferedReader JDK7 Esimerkki

JDK 7:stรค eteenpรคin try-with-resources poistaa finally lohko kokonaan. Mikรค tahansa suluissa ilmoitettu resurssi try lauseke suljetaan automaattisesti, kun lohko poistuu, luonnin kรครคnteisessรค jรคrjestyksessรค, vaikka poikkeus leviรคisikin:

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class ReadFileExample_jdk7 {

    private static final String FILENAME = "D:\\DukesDiary.txt";

    public static void main(String[] args) {

        try (BufferedReader br = new BufferedReader(new FileReader(FILENAME))) {

            String strCurrentLine;

            while ((strCurrentLine = br.readLine()) != null) {
                System.out.println(strCurrentLine);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Tรคmรค versio on lyhyempi ja turvallisempi, joten sitรค kannattaa suosia uudessa koodissa. Tiedoston lukeminen on vain yksi luokan kรคyttรถtapa; seuraavassa osiossa sitรค verrataan vaihtoehtoon, johon useimmat aloittelijat tarttuvat ensin.

BufferedReader vs. skanneri: kumpaa kรคyttรครค

Molemmat luokat lukevat tekstiรค, ja aloittelijat valitsevat usein yhden mielivaltaisesti. Ne ratkaisevat erilaisia โ€‹โ€‹ongelmia, ja vรครคrรค valinta ilmenee joko kรถmpelรถnรค manuaalisena jรคsentรคmisenรค tai heikkona suorituskyvynรค, kun syรถtemรครคrรค kasvaa tuhansiin riveihin. Alla oleva taulukko asettaa ne rinnakkain.

Aspect BufferedReader Skanneri
Palautukset Kokonaiset rivit merkkijonona Jรคsennetyt tokenit ja primitiivit
Sisรครคnrakennettu jรคsennys Ei โ€” jaat tai muunnat itsesi Kyllรค โ€” nextInt, nextDouble, seuraavaRivi
Oletuspuskuri 8192 merkkiรค 1024 merkkiรค
Nopeus suurilla tiedostoilla Nopeampi Hitaampi regex-tokenisoinnin vuoksi
Langan turvallisuus Synckronisoitu Ei synkronoitu
Parasta Suurten tiedostojen lukeminen rivi riviltรค Pieni interaktiivinen syรถte, joka vaatii kirjoitettuja arvoja

Valita BufferedReader, kun tavoitteena on selata tiedostoa nopeasti ja kรคsitellรค tekstiรค itse, ja Scanner, kun haluat kirjoitetut arvot ilman muunnoskoodin kirjoittamista. Jaa jokainen palautettu rivi Merkkijonojen jakomenetelmรค antaa BufferedReader hyรถdyntรครค skannerin mukavuutta suurimmalla nopeudella.

Konsolin syรถtteen lukeminen kรคyttรคmรคllรค BufferedReader

Sama luokka lukee nรคppรคimistรถsyรถtettรค, mikรค on hyรถdyllistรค pienille komentoriviohjelmille ja koodauksen haastesyรถtteelle. System.in on tavuvirta, joten sitรค ei voida luovuttaa Buffersuoraan edReaderista. InputStreamReader siltoja tavuista merkkeihin ja BufferedReader lisรครค sitten tehokkaan rivinluvun kyseisen sillan pรครคlle.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class ReadConsoleExample {

    public static void main(String[] args) throws IOException {

        // Bridge the System.in byte stream to a character stream
        try (BufferedReader reader =
                new BufferedReader(new InputStreamReader(System.in))) {

            System.out.print("Enter your name: ");
            String name = reader.readLine();

            System.out.print("Enter your age: ");
            // readLine always returns text, so convert it explicitly
            int age = Integer.parseInt(reader.readLine().trim());

            System.out.println("Hello " + name + ", age " + age);
        }
    }
}

Kolme yksityiskohtaa on syytรค muistaa. Ensinnรคkin, readLine() palauttaa aina merkkijonon, joten numeerinen syรถte on muunnettava Integer.parseInt tai vastaava, ja ei-numeerinen merkintรค heittรครค NumberFormatException โ€” rivittรครค muunnoksen, jos syรถtteeseen ei luoteta. Toiseksi, kutsu .trim() poistaa lopussa olevan rivinvaihdon, joka Windows konsolien liittรคminen, mikรค on yleinen syy jรคsennysvirheisiin. Kolmanneksi, vรคltรค lukijan sulkemista kierretyn System.in jos ohjelma tarvitsee konsolisyรถtettรค myรถhemminkin, koska kรครคreen sulkeminen sulkee alla olevan virran pysyvรคsti kyseiselle prosessille.

Ohjelmille, jotka lukevat useita arvoja, yhden rivin lukeminen ja sen jakaminen on paljon nopeampaa kuin kutsuminen readLine() toistuvasti, koska jokainen kutsu siirtyy kรคyttรถjรคrjestelmรครคn vasta puskurin tyhjentyessรค. Tรคmรค on tรคrkein syy, miksi kilpailevat ohjelmoijat suosivat BufferedReader skannerin kautta joukkosyรถttรถรค varten.

Vaikka koodi olisi oikein, kourallinen virheitรค esiintyy toistuvasti.

Yhteinen BufferedReader-virheet ja niiden korjaaminen

bridge BufferedReaderin virheet johtuvat tiedostopoluista, resurssien kรคsittelystรค tai merkistรถkoodauksesta pikemminkin kuin itse lukusilmukasta. Jokainen alla oleva virhe mainitsee poikkeuksen ja sen korjauksen.

  • Virheellinen pakomerkki: polussa kรคytetรครคn yhtรค kenoviivaa, kuten kohdassa "D:\DukesDiary.txt". Double se "D:\\DukesDiary.txt"tai kรคytรค vinoviivaa, joka Java hyvรคksyy Windows.
  • Tiedostoa ei lรถytynyt -poikkeus: polku on suhteessa tyรถhakemistoon, ei lรคhdetiedostoon. Tulosta new File(name).getAbsolutePath() nรคhdรค missรค Java oikeasti etsii.
  • NullPointerException ensimmรคisellรค lukukerralla: Lukijaa ei koskaan mรครคritetty, koska konstruktori heitti merkinnรคn, ja poikkeus nielaistiin. Tarkista poikkeusten kรคsittely ennen silmukkaa.
  • Sekavia tai kysymysmerkkien kaltaisia โ€‹โ€‹merkkejรค: tiedosto on UTF-8-muodossa, mutta FileReader kรคytti alustan oletusmerkistรถรค. Vรคlitรค merkistรถ eksplisiittisesti, esimerkiksi new InputStreamReader(new FileInputStream(f), StandardCharsets.UTF_8).
  • Striimi suljettu: Lukija suljettiin silmukan sisรคllรค tai sitรค kรคytettiin uudelleen try-with-resources-ominaisuuden pรครคttymisen jรคlkeen. Avaa uusi lukija jokaista tiedoston lรคpikulkua varten.

UKK

Kyllรค. Toinen konstruktoriargumentti asettaa puskurin merkeinรค, esimerkiksi new BufferedReader(reader, 16384)Oletusarvo 8192 sopii useimmille tiedostoille; sen nostaminen auttaa vain erittรคin suurissa perรคkkรคisissรค lukukerroissa.

Pienille tiedostoille kyllรค โ€‹โ€‹โ€” se palauttaa riviluettelon yhdellรค kutsulla. Suurille tiedostoille suositeltavampi vaihtoehto. Files.newBufferedReader or Files.lines, koska readAllLines pitรครค koko tiedostoa muistissa kerralla.

Kyllรค. AI Assistantit kirjoittavat finally-block cleanupin uudelleen try-with-resources-muotoon ja ehdottavat NIO-vastineita. Tarkista merkistรถ- ja poikkeustoiminta jรคlkikรคteen, koska luodut muunnokset usein poistavat eksplisiittisen koodauksen.

Tekoรคly lukee pinoa trace ja tunnistaa, onko syynรค vรครคrรค tyรถhakemisto, puuttuva kรคyttรถoikeus vai koodausvirhe. Se lyhentรครค vianmรครคritystรค, vaikka korjaus vaatii silti varmennusta oikeaa tiedostoa vasten.

Ei. readLine poistaa rivinpรครคttรคjรคmerkin, joten palautettu merkkijono ei sisรคllรค rivinvaihtoa lopussa. Tyhjรค rivi tiedostossa palauttaa siis tyhjรคn merkkijonon eikรค null-arvon.

Tiivistรค tรคmรค viesti seuraavasti: