Ako čítať súbor v prostredí Java

1. Prehľad

V tomto tutoriáli preskúmame rôzne spôsoby, ako čítať zo súboru v Jave.

Najskôr si ukážeme, ako pomocou štandardných tried Java načítať súbor z cesty triedy, adresy URL alebo zo súboru JAR.

Po druhé, uvidíme, ako prečítať obsah pomocou BufferedReader, Skener, StreamTokenizer, DataInputStream, SequenceInputStream, a FileChannel. Budeme tiež diskutovať o tom, ako čítať súbor kódovaný UTF-8.

Na záver preskúmame nové techniky načítania a čítania súborov v jazykoch Java 7 a Java 8.

Tento článok je súčasťou série „Java - Späť na základné“ tu na Baeldungu.

2. Inštalácia

2.1 Vstupný súbor

Vo väčšine príkladov v tomto článku si prečítame textový súbor s názvom súboru fileTest.txt ktorý obsahuje jeden riadok:

Ahoj, svet!

V niekoľkých príkladoch použijeme iný súbor. V týchto prípadoch výslovne spomenieme súbor a jeho obsah.

2.2 Pomocná metóda

Použijeme množinu príkladov testov, ktoré používajú iba základné triedy Java, a v testoch použijeme tvrdenia pomocou porovnávacích nástrojov Hamcrest.

Testy budú zdieľať spoločné readFromInputStream metóda, ktorá transformuje InputStream do String pre ľahšie uplatnenie výsledkov:

private String readFromInputStream (InputStream inputStream) vyvolá IOException {StringBuilder resultStringBuilder = nový StringBuilder (); try (BufferedReader br = new BufferedReader (new InputStreamReader (inputStream))) {String line; while ((line = br.readLine ())! = null) {resultStringBuilder.append (line) .append ("\ n"); }} return resultStringBuilder.toString (); }

Upozorňujeme, že existujú ďalšie spôsoby, ako dosiahnuť rovnaký výsledok. Niektoré alternatívy nájdete v tomto článku.

3. Čítanie súboru z triedy Classpath

3.1. Používanie štandardnej Javy

Táto časť vysvetľuje, ako čítať súbor, ktorý je k dispozícii pre triednu cestu. Prečítame si „ fileTest.txt ”Dostupné pod src / main / resources :

@Test public void givenFileNameAsAbsolutePath_whenUsingClasspath_thenFileData () {String expectData = "Dobrý deň, svet!"; Class clazz = FileOperationsTest.class; InputStream inputStream = clazz.getResourceAsStream ("/ fileTest.txt"); Reťazec data = readFromInputStream (inputStream); Assert.assertThat (data, containsString (expectData)); }

Vo vyššie uvedenom útržku kódu sme použili aktuálnu triedu na načítanie súboru pomocou getResourceAsStream metóda a prešla absolútna cesta k súboru, ktorý sa má načítať.

Rovnaká metóda je k dispozícii na a ClassLoader inštancia tiež:

ClassLoader classLoader = getClass (). GetClassLoader (); InputStream inputStream = classLoader.getResourceAsStream ("fileTest.txt"); Reťazec data = readFromInputStream (inputStream);

Získame classLoader aktuálnej triedy pomocou getClass (). getClassLoader () .

Hlavný rozdiel je v tom, že pri použití getResourceAsStream na a ClassLoader inštancia, cesta sa považuje za absolútnu počnúc od koreňa cesty triedy.

Pri použití proti a Trieda inštancia , cesta môže byť relatívna k balíku alebo absolútna cesta, ktorá je naznačená úvodnou lomkou.

Samozrejme nezabudnite, že v praxi by mali byť otvorené prúdy vždy uzavreté, ako InputStream v našom príklade:

InputStream inputStream = null; skúste {File file = new File (classLoader.getResource ("fileTest.txt"). getFile ()); inputStream = nový FileInputStream (súbor); // ...} konečne {if (inputStream! = null) {vyskúšať {inputStream.close (); } catch (IOException e) {e.printStackTrace (); }}}

3.2. Pomocou commons-io Knižnica

Ďalšou bežnou možnosťou je použitie FileUtils trieda commons-io balenie:

@Test public void givenFileName_whenUsingFileUtils_thenFileData () {String expectData = "Hello, world!"; ClassLoader classLoader = getClass (). GetClassLoader (); File file = new File (classLoader.getResource ("fileTest.txt"). GetFile ()); Reťazec data = FileUtils.readFileToString (súbor, "UTF-8"); assertEquals (expectData, data.trim ()); }

Tu míňame Súbor namietajú voči metóde readFileToString () z FileUtils trieda. Táto trieda obslužných programov dokáže načítať obsah bez nutnosti písania akéhokoľvek štandardného kódu na vytvorenie súboru InputStream inštancie a načítať údaje.

Rovnaká knižnica tiež ponúka IOUtilstrieda:

@Test public void givenFileName_whenUsingIOUtils_thenFileData () {String expectData = "Hello, world!"; FileInputStream fis = nový FileInputStream ("src / test / resources / fileTest.txt"); Reťazec data = IOUtils.toString (fis, "UTF-8"); assertEquals (expectData, data.trim ()); }

Tu míňame FileInputStream namietajú voči metóde natiahnuť() z IOUtils trieda. Táto trieda obslužných programov dokáže načítať obsah bez nutnosti písania akéhokoľvek štandardného kódu na vytvorenie súboru InputStream inštancie a načítať údaje.

4. Čítanie s BufferedReader

Poďme sa teraz zamerať na rôzne spôsoby analýzy obsahu súboru.

Začneme jednoduchým spôsobom čítania zo súboru pomocou Vyrovnávacia pamäť:

@Test public void whenReadWithBufferedReader_thenCorrect () vyvolá IOException {String expect_value = "Hello, world!"; Reťazcový pilník; Čítačka BufferedReader = nový BufferedReader (nový FileReader (súbor)); Reťazec currentLine = reader.readLine (); reader.close (); assertEquals (expect_value, currentLine); }

Poznač si to readLine () vráti sa nulový keď sa dosiahne koniec súboru.

5. Čítanie zo súboru pomocou Java NIO

V JDK7 bol balík NIO významne aktualizovaný.

Pozrime sa na príklad pomocou Súbory triedy a readAllLines metóda. The readAllLines metóda akceptuje a Cesta.

Cesta triedy možno považovať za aktualizáciu java.io.Súbor s niektorými ďalšími operáciami.

5.1. Čítanie malého súboru

Nasledujúci kód ukazuje, ako čítať malý súbor pomocou nového súboru Súbory trieda:

@ Test public void whenReadSmallFileJava7_thenCorrect () vyvolá IOException {String expect_value = "Hello, world!"; Path path = Paths.get ("src / test / resources / fileTest.txt"); Reťazec read = Files.readAllLines (cesta) .get (0); assertEquals (expect_value, read); }

Upozorňujeme, že môžete použiť readAllBytes () tiež, ak potrebujete binárne údaje.

5.2. Čítanie veľkého súboru

Ak chceme prečítať veľký súbor s Súbory triedy, môžeme použiť Vyrovnávacia pamäť:

Nasledujúci kód načíta súbor pomocou nového Súbory triedy a BufferedReader:

@ Test public void whenReadLargeFileJava7_thenCorrect () vyvolá IOException {String expect_value = "Hello, world!"; Path path = Paths.get ("src / test / resources / fileTest.txt"); Čítačka BufferedReader = Files.newBufferedReader (cesta); Reťazec line = reader.readLine (); assertEquals (expect_value, line); }

5.3. Čítanie súboru pomocou Files.lines ()

JDK8 ponúka riadky () metóda vo vnútri Súbory trieda. Vracia a Prúd prvkov reťazca.

Pozrime sa na príklad toho, ako čítať údaje do bajtov a dekódovať pomocou znakovej sady UTF-8.

Nasledujúci kód načíta súbor pomocou nového Files.lines ():

@Test public void givenFilePath_whenUsingFilesLines_thenFileData () {String expectData = "Hello, world!"; Cesta cesty = Paths.get (getClass (). GetClassLoader () .getResource ("fileTest.txt"). ToURI ()); Stream lines = Files.lines (cesta); Reťazec data = lines.collect (Collectors.joining ("\ n")); lines.close (); Assert.assertEquals (expectData, data.trim ()); }

Pri použití Streamu s IO kanálmi, ako sú operácie so súbormi, musíme stream explicitne uzavrieť pomocou Zavrieť() metóda.

Ako vidíme, Súbory API ponúka ďalší jednoduchý spôsob, ako načítať obsah súboru do formátu String.

V ďalších častiach sa pozrime na ďalšie, menej bežné metódy čítania súboru, ktoré môžu byť v niektorých situáciách vhodné.

6. Čítanie s Skener

Ďalej použijeme a Skener čítať zo súboru. Tu použijeme medzery ako oddeľovač:

@Test public void whenReadWithScanner_thenCorrect () hodí IOException {String file = "src / test / resources / fileTest.txt"; Skener skener = nový skener (nový súbor (súbor)); scanner.useDelimiter (""); assertTrue (scanner.hasNext ()); assertEquals ("Dobrý deň,", scanner.next ()); assertEquals ("svet!", scanner.next ()); scanner.close (); }

Upozorňujeme, že predvolený oddeľovač je medzery, ale s a sa dá použiť viac oddeľovačov Skener.

Trieda Scanner je užitočná pri čítaní obsahu z konzoly alebo v prípade, že obsah obsahuje primitívne hodnoty, so známym oddeľovačom (napr. zoznam celých čísel oddelených medzerou).

7. Čítanie s StreamTokenizer

Ďalej prečítajme textový súbor do tokenov pomocou a StreamTokenizer.

Tokenizer funguje - najskôr musíme zistiť, aký je ďalší token - reťazec alebo číslo; robíme to tak, že sa pozrieme na tokenizer.ttype lúka.

Potom si prečítame skutočný token založený na tomto type:

  • tokenizer.nval - ak bolo typom číslo
  • tokenizer.sval - ak bol typ String

V tomto príklade použijeme iný vstupný súbor, ktorý jednoducho obsahuje:

Ahoj 1

Nasledujúci kód načíta zo súboru reťazec aj číslo:

@Test public void whenReadWithStreamTokenizer_thenCorrectTokens () vyvolá IOException {String file = "src / test / resources / fileTestTokenizer.txt"; Čítačka FileReader = nový FileReader (súbor); StreamTokenizer tokenizer = nový StreamTokenizer (čítačka); // token 1 tokenizer.nextToken (); assertEquals (StreamTokenizer.TT_WORD, tokenizer.ttype); assertEquals ("Dobrý deň", tokenizer.sval); // token 2 tokenizer.nextToken (); assertEquals (StreamTokenizer.TT_NUMBER, tokenizer.ttype); assertEquals (1, tokenizer.nval, 0,0000001); // token 3 tokenizer.nextToken (); assertEquals (StreamTokenizer.TT_EOF, tokenizer.ttype); reader.close (); }

Všimnite si, ako sa na konci používa koniec tokenu súboru.

Tento prístup je užitočný na analýzu vstupného toku do tokenov.

8. Čítanie s DataInputStream

Môžeme použiť DataInputStream na čítanie binárnych alebo primitívnych údajov zo súboru.

Nasledujúci test načíta súbor pomocou a DataInputStream:

@ Test public void whenReadWithDataInputStream_thenCorrect () vyvolá IOException {String expectValue = "Ahoj, svet!"; Reťazcový pilník; Výsledok reťazca = null; Čítačka DataInputStream = nový DataInputStream (nový FileInputStream (súbor)); int nBytesToRead = reader.available (); if (nBytesToRead> 0) {byte [] bajtov = nový bajt [nBytesToRead]; reader.read (bajty); výsledok = nový reťazec (bajty); } assertEquals (expectValue, result); }

9. Čítanie s FileChannel

Ak čítame veľký súbor, FileChannel môže byť rýchlejší ako štandardné IO.

Nasledujúci kód načíta dátové bajty zo súboru pomocou FileChannel a RandomAccessFile:

@Test public void whenReadWithFileChannel_thenCorrect () hodí IOException {String expect_value = "Hello, world!"; Reťazcový súbor = "src / test / resources / fileTest.txt"; Čítačka RandomAccessFile = nový RandomAccessFile (súbor, "r"); Kanál FileChannel = reader.getChannel (); int bufferSize = 1024; if (bufferSize> channel.size ()) {bufferSize = (int) channel.size (); } ByteBuffer buff = ByteBuffer.allocate (bufferSize); channel.read (buff); buff.flip (); assertEquals (expect_value, new String (buff.array ())); channel.close (); reader.close (); }

10. Čítanie súboru kódovaného v UTF-8

Teraz sa pozrime, ako čítať súbor kódovaný UTF-8 pomocou BufferedReader. V tomto príklade si prečítame súbor, ktorý obsahuje čínske znaky:

@ Test public void whenReadUTFEncodedFile_thenCorrect () vyvolá IOException {String expect_value = "青 空"; Reťazcový súbor = "src / test / resources / fileTestUtf8.txt"; Čítačka BufferedReader = nový BufferedReader (nový InputStreamReader (nový FileInputStream (súbor), "UTF-8")); Reťazec currentLine = reader.readLine (); reader.close (); assertEquals (expect_value, currentLine); }

11. Čítanie obsahu z adresy URL

Na čítanie obsahu z adresy URL použijeme „/”URL v našom príklade ako:

@Test public void givenURLName_whenUsingURL_thenFileData () {String expectData = "Baeldung"; URL urlObject = nová URL ("/"); URLConnection urlConnection = urlObject.openConnection (); InputStream inputStream = urlConnection.getInputStream (); Reťazec data = readFromInputStream (inputStream); Assert.assertThat (data, containsString (expectData)); }

Existujú aj alternatívne spôsoby pripojenia k adrese URL. Tu sme použili URL a URLConnection trieda dostupná v štandardnej SDK.

12. Čítanie súboru z JAR

Na prečítanie súboru, ktorý je umiestnený v súbore JAR, budeme potrebovať súbor JAR, ktorý je v ňom obsiahnutý. Pre náš príklad budeme čítať „LICENCIA.txtZ „hamcrest-library-1.3.jar”Súbor:

@Test public void givenFileName_whenUsingJarFile_thenFileData () {String expectData = "Licencia BSD"; Trieda clazz = Matchers.class; InputStream inputStream = clazz.getResourceAsStream ("/ LICENSE.txt"); Reťazec data = readFromInputStream (inputStream); Assert.assertThat (data, containsString (expectData)); }

Tu sa chceme načítať LICENCIA.txt ktorá sa nachádza v knižnici Hamcrest, takže použijeme Matcher trieda, ktorá pomáha získať zdroj. Rovnaký súbor je možné načítať aj pomocou načítavača triedy.

13. Záver

Ako vidíte, existuje veľa možností na načítanie súboru a čítanie údajov z neho pomocou obyčajnej Javy.

Môžete načítať súbor z rôznych umiestnení, ako sú napríklad classpath, URL alebo jar.

Potom môžete použiť BufferedReader čítať riadok po riadku, Skener čítať pomocou rôznych oddeľovačov, StreamTokenizer načítať súbor do tokenov, DataInputStream čítať binárne dáta a primitívne dátové typy, Stream SequenceInput prepojiť viac súborov do jedného streamu, FileChannel rýchlejšie čítať z veľkých súborov atď.

Zdrojový kód nájdete v nasledujúcom úložisku GitHub.


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