Java BufferedReader: Kako pročitati datoteku s primjerom

⚡ Pametni sažetak

Java BufferedReader čita tekst iz ulaznog toka međuspremnikom znakova, što čitanje datoteke redak po redak čini brzim i jednostavnim. Prelomping FileReader unutra BufferedReader i WCping na readLine dok ne vrati null ispisuje cijelu datoteku.

  • ???? Osnovna svrha: BufferedReader obavija svaki Reader čije su operacije čitanja skupe, smanjujući pojedinačna čitanja u odnosu na temeljni tok.
  • 🔁 Petlja čitanja: readLine vraća jedan redak po pozivu i null na kraju datoteke, pa while petlja na tom rezultatu prolazi kroz cijelu datoteku.
  • 🧱 Izbjegnuti putevi: A Windows put unutar Java Niz zahtijeva dvostruku obrnutu kosu crtu, inače kompajler odbacuje nevažeći escape niz.
  • ♻️ Oslobađanje resursa: Zatvaranje čitača oslobađa temeljni identifikator datoteke; try-with-resources izvršava to zatvaranje automatski.
  • ⌨️ Ulaz u konzolu: Zamotajteping System.in u InputStreamReaderu omogućuje istoj klasi čitanje unosa s tipkovnice umjesto datoteke.
  • ⚖️ Kontrast skenera: BufferedReader je brži i vraća sirove linije, dok Scanner izravno parsira tokene i primitivne tipove.
  • 🔤 Oprez u vezi sa skupom znakova: FileReader primjenjuje zadani skup znakova, pa eksplicitnim navođenjem jednog izbjegavate iskrivljene znakove na različitim računalima.

BufferedReader u Java

Kako čitati datoteku u Java?

Java pruža nekoliko mehanizama za čitanje iz datoteke. Najkorisniji paket za to je java.io, čiji trbušnjacitract Reader Klasa definira čitanje niza znakova. java.io.BufferedReader je konkretna podklasa koja se koristi za učinkovito čitanje u retku.

Što je BufferedReader u Java?

BufferedReader je Java klasa koja čita tekst iz ulaznog toka, kao što je datoteka, međuspremnikom znakova tako da se znakovi, nizovi i retki učinkovito čitaju. Bez međuspremnika, svaki zahtjev za čitanje od strane Readera pokreće odgovarajući zahtjev za čitanje temeljnog toka znakova ili bajtova.

Stoga je preporučljivo zamotati BufferedReader oko bilo kojeg Čitača čiji read() operacije mogu biti skupe, kao što su FileReader i InputStreamReaderTipična upotreba prosljeđuje putanju datoteke čitaču na sljedeći način:

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

Ovo učitava datoteku u objReaderZatim iterirate kroz sadržaj datoteke i ispisujete svaki redak. Petlja while u donjem kodu čita datoteku dok ne dođe do kraja datoteke.

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

strCurrentLine drži trenutnu liniju i objReader.readLine() vraća niz znakova. Petlja stoga nastavlja iterirati sve dok vraćena vrijednost nije null i zaustavlja se na prvom null-u, što signalizira kraj datoteke.

BufferPrimjer edReader

Donji kod je potpun Java BufferPrimjer edReadera:

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();
            }
        }
    }
}

Bilješka: The finally blok je važan. Jamči da objReader.close() izvršava se bez obzira je li bačena iznimka ili ne, što oslobađa temeljni identifikator datoteke i zadržava upravljanje memorijom predvidljivo. Ugniježđeni pokušaj unutra finally je potrebno jer close() sama izjavljuje IOException.

BufferPrimjer edReader JDK7

Od JDK 7 nadalje, try-with-resources uklanja finally blokirati u cijelosti. Bilo koji resurs deklariran u zagradama try Naredba se automatski zatvara kada blok izađe, obrnutim redoslijedom stvaranja, čak i ako se iznimka širi:

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();
        }
    }
}

Ova verzija je kraća i sigurnija, pa je to oblik koji treba preferirati u novom kodu. Čitanje datoteke samo je jedna od upotreba klase; sljedeći odjeljak uspoređuje je s alternativom koju većina početnika prvo koristi.

BufferedReader vs. skener: koji koristiti

Oba razreda čitaju tekst, a početnici često proizvoljno odaberu jedan. Rješavaju različite probleme, a pogrešan izbor očituje se ili kao nespretno ručno parsiranje ili slaba propusnost kada ulaz naraste na tisuće redaka. Tablica u nastavku ih uspoređuje.

Aspekt BufferedReader Skener
Povratak Cijeli redovi kao niz znakova Raščlanjeni tokeni i primitivi
Ugrađeno parsiranje Ne — ti se dijeliš ili pretvaraš Da — nextInt, sljedećiDouble, sljedeći redak
Zadani međuspremnik 8192 likovi 1024 likovi
Brzina rada s velikim datotekama Brže Sporije, zbog tokenizacije regularnih izraza
Sigurnost niti Synckroniziran Nije sinkronizirano
Najbolje za Čitanje velikih datoteka redak po redak Mali interaktivni unos koji zahtijeva unesene vrijednosti

Odaberite BufferedReader kada je cilj brzo kretanje kroz datoteku i samostalno rukovanje tekstom, te Scanner kada želite upisati vrijednosti bez pisanja koda za pretvorbu. Razdvajanje svakog vraćenog retka s Metoda dijeljenja stringova daje BufferedReader većinu pogodnosti skenera ostvaruje većom brzinom.

Kako čitati ulaz iz konzole pomoću BufferedReader

Ista klasa čita unos s tipkovnice, što je korisno za male programe naredbenog retka i za unos u izazovima kodiranja. System.in je tok bajtova, tako da se ne može predati BufferedReader izravno. InputStreamReader premošćuje bajtove sa znakovima i BufferedReader zatim dodaje učinkovito čitanje redaka na vrh tog mosta.

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);
        }
    }
}

Vrijedi zapamtiti tri detalja. Prvo, readLine() uvijek vraća niz znakova, pa se numerički unos mora pretvoriti s Integer.parseInt ili slično, a nenumerički unos baca NumberFormatException — omotajte pretvorbu ako ulaz nije pouzdan. Drugo, pozivanje .trim() uklanja završni znak za povratak valjka koji Windows konzole dodaju, što je čest uzrok neuspjeha parsiranja. Treće, izbjegavajte zatvaranje čitača omotanog oko System.in ako programu kasnije i dalje trebaju unos iz konzole, jer zatvaranje omotača trajno zatvara temeljni stream za taj proces.

Za programe koji čitaju mnogo vrijednosti, čitanje jednog retka i njegovo dijeljenje je puno brže od pozivanja readLine() više puta, budući da svaki poziv prelazi u operativni sustav samo kada se međuspremnik isprazni. To je glavni razlog zašto konkurentni programeri preferiraju BufferedReader umjesto Skenera za skupni unos.

Čak i s ispravnim kodom, nekoliko pogrešaka se ponavlja.

Zajednički BufferGreške u edReaderu i kako ih ispraviti

most BufferKvarovi edReadera nastaju zbog putanja datoteka, rukovanja resursima ili kodiranja znakova, a ne zbog same petlje čitanja. Svaka pogreška u nastavku navodi svoju iznimku i rješenje.

  • Nedozvoljeni znak za izlaz: put koristi jednu obrnutu kosu crtu, kao u "D:\DukesDiary.txt". Double to "D:\\DukesDiary.txt"ili upotrijebite kosu crtu naprijed, koja Java prihvaća Windows.
  • Iznimka datotekeNijePronađena: Putanja je relativna u odnosu na radni direktorij, a ne na izvornu datoteku. Ispis new File(name).getAbsolutePath() vidjeti gdje Java zapravo traži.
  • NullPointerException pri prvom čitanju: Čitač nikada nije dodijeljen jer je konstruktor izbacio iznimku, a iznimka je progutana. Provjerite rukovanje izuzetkom prije petlje.
  • Iskrivljeni ili upitni znakovi: datoteka je UTF-8, ali FileReader primijenjen je zadani skup znakova platforme. Eksplicitno proslijedite skup znakova, na primjer new InputStreamReader(new FileInputStream(f), StandardCharsets.UTF_8).
  • Stream je zatvoren: Čitač je zatvoren unutar petlje ili ponovno upotrijebljen nakon završetka try-with-resources. Otvorite novi čitač za svaki prolaz kroz datoteku.

Pitanja i odgovori

Da. Drugi argument konstruktora postavlja međuspremnik u znakovima, na primjer new BufferedReader(reader, 16384)Zadana vrijednost 8192 odgovara većini datoteka; podizanje vrijednosti pomaže samo kod vrlo velikih sekvencijalnih čitanja.

Za male datoteke, da — vraća popis redaka u jednom pozivu. Za velike datoteke preferiram Files.newBufferedReader or Files.lines, jer readAllLines drži cijelu datoteku u memoriji odjednom.

Da. AI Asistenti prepisuju finally-block cleanup u try-with-resources i predlažu NIO ekvivalente. Nakon toga provjerite ponašanje skupa znakova i iznimki, jer generirane konverzije često izostavljaju eksplicitno kodiranje.

AI čita stog trace i identificira je li uzrok pogrešan radni direktorij, nedostajuća dozvola ili neusklađenost kodiranja. Skraćuje dijagnozu, iako je za ispravak i dalje potrebna provjera u odnosu na stvarnu datoteku.

Ne. readLine uklanja terminator retka, pa vraćeni niz znakova ne sadrži završni znak za novi redak. Prazan redak u datoteci stoga vraća prazan niz znakova, a ne null.

Sažmite ovu objavu uz: