Java BufferedReader: Kuidas faili lugeda koos näitega
⚡ Nutikas kokkuvõte
Java BufferedReader loeb sisendvoost teksti märke puhverdades, mis muudab rida-realt failide lugemise kiireks ja lihtsaks.ping FileReader sees BufferedReader ja tualettruumping readLine'il, kuni see tagastab nulli, prindib terve faili.
Kuidas faili sisse lugeda Java?
Java pakub failist lugemiseks mitu mehhanismi. Selleks on kõige kasulikum pakett java.io, kelle kõhulihasedtract Reader Klass defineerib märgivoo lugemise. java.io.BufferedReader on konkreetne alamklass, mida kasutatakse efektiivseks reapõhiseks lugemiseks.
Mis on BufferedReader sisse Java?
BufferedReader on Java Klass, mis loeb sisendvoost (nt failist) teksti, puhverdades märke nii, et märke, massiive ja ridu loetakse tõhusalt. Ilma puhverdamiseta käivitab iga lugejale esitatud lugemispäring vastava lugemispäringu aluseks oleva märgi- või baidivoo vastu.
Seetõttu on soovitatav mähkida BufferedReader iga lugeja ümber, kelle read() operatsioonid võivad olla kulukad, näiteks FileReader ja InputStreamReaderTüüpiline kasutusviis edastab failitee lugejale järgmiselt:
// Note the doubled backslash: a single \ starts an escape sequence objReader = new BufferedReader(new FileReader("D:\\DukesDiary.txt"));
See laadib faili sisse objReaderSeejärel käid faili sisu läbi ja prindid iga rea välja. Allolevas koodis olev while-tsükkel loeb faili kuni selle lõppu jõudmiseni.
while ((strCurrentLine = objReader.readLine()) != null) { System.out.println(strCurrentLine); }
strCurrentLine hoiab praegust rida ja objReader.readLine() tagastab stringi. Seega tsükkel itereerib seni, kuni tagastatud väärtus ei ole null, ja peatub esimese nulli juures, mis annab märku faili lõpust.
BufferedReaderi näide
Allolev kood on täielik Java BufferedReaderi näide:
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(); } } } }
Märge: . finally plokk on oluline. See garanteerib, et objReader.close() käivitub olenemata sellest, kas tekkis erand või mitte, mis vabastab aluseks oleva faili käepideme ja hoiab selle alles. mäluhaldus etteaimatav. Pesastatud katse sees finally on vajalik, sest close() ise deklareerib IOException.
BufferedReader JDK7 näide
Alates JDK 7-st eemaldab try-with-resources selle finally plokk tervikuna. Iga sulgudes deklareeritud ressurss try lause suletakse automaatselt, kui plokk väljub, loomisele vastupidises järjekorras, isegi kui erand levib:
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(); } } }
See versioon on lühem ja turvalisem, seega on see uue koodi puhul eelistatav vorm. Faili lugemine on ainult üks klassi kasutusvõimalustest; järgmises osas võrreldakse seda alternatiiviga, milleni enamik algajaid esimesena jõuab.
BufferedReader vs skanner: kumba kasutada
Mõlemad kursused loevad teksti ja algajad valivad sageli ühe suvaliselt. Nad lahendavad erinevaid ülesandeid ning vale valik ilmneb kas kohmaka käsitsi parsimise või kehva läbilaskevõimena, kui sisend kasvab tuhandete ridadeni. Allolev tabel seab need kõrvuti.
| Aspekt | BufferedReader | Skanner |
|---|---|---|
| Tagastamine | Terved read stringina | Parsitud märgid ja primitiivid |
| Sisseehitatud parsimine | Ei — sa jagad või konverteerid ennast | Jah — nextInt, nextDouble, järgmine rida |
| Vaikimisi puhver | 8192 tähemärki | 1024 tähemärki |
| Kiirus suurte failidega | Kiiremini | Aeglasem regulaaravaldiste tokeniseerimise tõttu |
| Keerme ohutus | Synckroonitud | Pole sünkroonitud |
| Parim on | Suurte failide rida-realt lugemine | Väike interaktiivne sisend, mis vajab trükitud väärtusi |
Vali BufferedReader, kui eesmärk on failis kiiresti liikuda ja teksti ise hallata, ning Scanner, kui soovite tipitud väärtusi ilma teisenduskoodi kirjutamata. Iga tagastatud rea jagamine Stringi jagamise meetod annab BufferedReader suurem osa skanneri mugavusest suuremal kiirusel.
Kuidas konsooli sisendit lugeda, kasutades BufferedReader
Sama klass loeb klaviatuuril sisestatud andmeid, mis on kasulik väikeste käsureaprogrammide ja kodeerimisväljakutsetega sisendi jaoks. System.in on baitvoog, seega ei saa seda kellelegi üle anda Bufferotse edReaderisse. An InputStreamReader ühendab baidid tähemärkidega ja BufferSeejärel lisab edReader sellele sillale tõhusa realugemise.
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); } } }
Kolm detaili tasub meeles pidada. Esiteks, readLine() tagastab alati stringi, seega tuleb numbriline sisend teisendada Integer.parseInt või sarnane ja mittenumbriline kirje viskab NumberFormatException — teisendust murtakse, kui sisend pole usaldusväärne. Teiseks, kutsutakse .trim() eemaldab lõpus oleva kelguvahetuse, mis Windows konsoolide lisamine, mis on parsimisvigade sagedane põhjus. Kolmandaks, vältige lugeja sulgemist, mis on mähitud ümber System.in kui programm vajab hiljem ikkagi konsooli sisendit, sest ümbrise sulgemine sulgeb selle protsessi jaoks aluseks oleva voo jäädavalt.
Programmide puhul, mis loevad palju väärtusi, on ühe rea lugemine ja selle jagamine palju kiirem kui programmi käivitamine. readLine() korduvalt, kuna iga kutse jõuab operatsioonisüsteemi alles siis, kui puhver tühjeneb. See on peamine põhjus, miks võistlusprogrammeerijad eelistavad BufferMassilise sisestamise jaoks skanneri asemel edReader.
Isegi korrektse koodi korral ilmub mitu viga korduvalt.
ühine BufferedReaderi vead ja kuidas neid parandada
sild BufferedReaderi tõrked tulenevad pigem failiteedest, ressursside käitlemisest või märgikodeeringust kui lugemistsüklist endast. Iga allpool olev viga nimetab oma erandi ja selle paranduse.
- Lubamatu põgenemismärk: tee kasutab ühte kaldkriipsu, nagu näiteks
"D:\DukesDiary.txt". Double tal"D:\\DukesDiary.txt"või kasutage kaldkriipsu, mis Java aktsepteerib Windows. - Faili ei leitud erand: tee on töökataloogi, mitte lähtefaili suhtes. Prindi
new File(name).getAbsolutePath()et näha, kus Java tegelikult otsib. - NullPointerException esimesel lugemisel: Lugejat ei määratud kunagi, sest konstruktor viskas väärtuse „viske“ ja erand neelati alla. Kontrollige erandite käsitlemine enne silmust.
- Segased või küsimärgikujulised tähemärgid: fail on UTF-8, aga
FileReaderrakendas platvormi vaikekoodistikku. Edasta koodistik selgesõnaliselt, näiteksnew InputStreamReader(new FileInputStream(f), StandardCharsets.UTF_8). - Otseülekanne suletud: Lugeja suleti tsükli sees või kasutati seda uuesti pärast try-with-resources'i lõppu. Avage iga faili läbimise korral uus lugeja.

