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: