Fájl olvasása Java-ban

1. Áttekintés

Ebben az oktatóanyagban különböző módokat fogunk felfedezni Java fájlból olvasható.

Először meglátjuk, hogyan lehet betölteni egy fájlt az osztályútvonalról, egy URL-ből vagy egy JAR fájlból, standard Java osztályok használatával.

Másodszor, meglátjuk, hogyan olvassuk el a tartalmat BufferedReader, Scanner, StreamTokenizer, DataInputStream, SequenceInputStream, és FileChannel. Ezenkívül megvitatjuk az UTF-8 kódolású fájl olvasását.

Végül feltárjuk a fájlok Java 7 és Java 8 rendszerbe történő betöltésének és olvasásának új technikáit.

Ez a cikk a „Java - Vissza az alapokhoz” sorozat része, itt, Baeldungon.

2. Beállítás

2.1 Bemeneti fájl

A cikk legtöbb példájában egy fájlnévvel ellátott szöveges fájlt fogunk olvasni fileTest.txt amely egy sort tartalmaz:

Helló Világ!

Néhány példában egy másik fájlt fogunk használni. Ezekben az esetekben kifejezetten megemlítjük a fájlt és annak tartalmát.

2.2 Segítő módszer

Csak a Java alaposztályokat használó tesztpéldányokat fogunk használni, a tesztek során pedig Hamcrest-illesztõket használó állításokat.

A tesztek közösek lesznek readFromInputStream módszer, amely átalakítja az an InputStream nak nek Húr az eredmények könnyebb érvényesítése érdekében:

privát karakterlánc readFromInputStream (InputStream inputStream) dobja az IOException {StringBuilder resultStringBuilder = új StringBuilder (); try (BufferedReader br = new BufferedReader (új InputStreamReader (inputStream))) {String sor; while ((line = br.readLine ())! = null) {resultStringBuilder.append (line) .append ("\ n"); }} return resultStringBuilder.toString (); }

Ne feledje, hogy más módon is elérheti ugyanazt az eredményt. Néhány alternatívát ebben a cikkben talál.

3. Fájl elolvasása a Classpath-ról

3.1. Standard Java használatával

Ez a szakasz elmagyarázza, hogyan lehet egy osztályúton elérhető fájlt olvasni. Elolvassuk a fileTest.txt Alatt elérhető src / main / resources :

@Test public void givenFileNameAsAbsolutePath_whenUsingClasspath_thenFileData () {String várhatóData = "Helló, világ!"; Class clazz = FileOperationsTest.class; InputStream inputStream = clazz.getResourceAsStream ("/ fileTest.txt"); Karakterlánc-adatok = readFromInputStream (inputStream); Assert.assertThat (adatok, tartalmazString (vártData)); }

A fenti kódrészletben az aktuális osztályt használtuk egy fájl betöltésére getResourceAsStream metódust, és átadta a fájl abszolút elérési útját a betöltéshez.

Ugyanez a módszer érhető el a ClassLoader például:

ClassLoader classLoader = getClass (). GetClassLoader (); InputStream inputStream = classLoader.getResourceAsStream ("fileTest.txt"); Karakterlánc-adatok = readFromInputStream (inputStream);

Megszerezzük a classLoader a jelenlegi osztály használatával getClass (). getClassLoader () .

A fő különbség az, hogy a getResourceAsStream rajta ClassLoader Például az elérési utat abszolútként kezeljük az osztályút gyökerétől kezdve.

Ha a-val szemben alkalmazzák Osztály példa , az útvonal lehet a csomaghoz viszonyítva, vagy egy abszolút útvonal, amelyre a vezető perjel utal.

Természetesen vegye figyelembe, hogy a gyakorlatban a nyitott folyamokat mindig be kell zárni, például a InputStream példánkban:

InputStream inputStream = null; próbálja meg a {File file = new File (classLoader.getResource ("fileTest.txt"). getFile ()) parancsot; inputStream = új FileInputStream (fájl); // ...} végül {if (inputStream! = null) {próbálkozzon az {inputStream.close (); } catch (IOException e) {e.printStackTrace (); }}}

3.2. Használni a commons-io Könyvtár

Egy másik gyakori lehetőség a FileUtils osztálya commons-io csomag:

@Test public void givenFileName_whenUsingFileUtils_thenFileData () {String várhatóData = "Helló, világ!"; ClassLoader classLoader = getClass (). GetClassLoader (); Fájlfájl = új Fájl (classLoader.getResource ("fileTest.txt"). GetFile ()); String data = FileUtils.readFileToString (fájl, "UTF-8"); assertEquals (vártData, data.trim ()); }

Itt adjuk át a File kifogásolja a módszert readFileToString () nak,-nek FileUtils osztály. Ez a segédosztály képes betölteni a tartalmat anélkül, hogy bármilyen kazánlap kódot kellene írni egy InputStream példány és adatokat olvas.

Ugyanez a könyvtár kínálja a IOUtilsosztály:

@Test public void givenFileName_whenUsingIOUtils_thenFileData () {String várhatóData = "Helló, világ!"; FileInputStream fis = új FileInputStream ("src / test / resources / fileTest.txt"); Karakterlánc-adatok = IOUtils.toString (fis, "UTF-8"); assertEquals (vártData, data.trim ()); }

Itt adjuk át a FileInputStream kifogásolja a módszert toString () nak,-nek IOUtils osztály. Ez a segédosztály képes betölteni a tartalmat anélkül, hogy bármilyen kazánlap kódot kellene írni egy InputStream példány és olvassa el az adatokat.

4. Olvasás vele BufferedReader

Most koncentráljunk a fájl tartalmának elemzésének különböző módjaira.

Kezdjük egy egyszerű módszerrel, amellyel a fájl segítségével olvashatunk BufferedReader:

@Test public void whenReadWithBufferedReader_thenCorrect () dobja az IOException-t {String várható_érték = "Helló, világ!"; String fájl; BufferedReader olvasó = new BufferedReader (új FileReader (fájl)); String currentLine = olvasó.readLine (); olvasó.zárja (); assertEquals (várható_érték, currentLine); }

Vegye figyelembe, hogy readLine () vissza fog térni nulla amikor elérte a fájl végét.

5. Olvasás fájlból a Java NIO használatával

A JDK7-ben az NIO csomag jelentősen frissült.

Nézzünk meg egy példát a Fájlok osztály és a readAllLines módszer. A readAllLines módszer elfogadja a Pálya.

Pálya osztály tekinthető a java.io.Fájl néhány további művelettel.

5.1. Kis fájl olvasása

A következő kód bemutatja, hogyan olvasható el egy kis fájl az új használatával Fájlok osztály:

@Test public void whenReadSmallFileJava7_thenCorrect () IOException dobja {String várható_érték = "Helló, világ!"; Elérési útvonal = Paths.get ("src / test / resources / fileTest.txt"); Karaktersorozat = Files.readAllLines (elérési út) .get (0); assertEquals (várható_érték, olvasás); }

Ne feledje, hogy használhatja a readAllBytes () módszer, ha bináris adatokra van szüksége.

5.2. Nagy fájl olvasása

Ha egy nagy fájlt akarunk elolvasni a Fájlok osztályban használhatjuk a BufferedReader:

A következő kód beolvassa a fájlt az új használatával Fájlok osztály és BufferedReader:

@Test public void, amikorReadLargeFileJava7_thenCorrect () dobja az IOException-t {String várható_érték = "Helló, világ!"; Elérési útvonal = Paths.get ("src / test / resources / fileTest.txt"); BufferedReader reader = Files.newBufferedReader (elérési út); Karakterlánc = olvasó.readLine (); assertEquals (várható_érték, sor); }

5.3. Fájl olvasása a Files.lines ()

A JDK8 kínálja a vonalak () módszer a Fájlok osztály. Visszaadja a Folyam karakterlánc elemekből.

Nézzünk meg egy példát arra, hogyan lehet adatokat bájtokba olvasni és dekódolni az UTF-8 karakterkészlet használatával.

A következő kód beolvassa a fájlt az új használatával Files.lines ():

@Test public void givenFilePath_whenUsingFilesLines_thenFileData () {String várhatóData = "Helló, világ!"; Elérési útvonal = Paths.get (getClass (). GetClassLoader () .getResource ("fileTest.txt"). ToURI ()); Stream vonalak = Files.lines (elérési út); Karakterlánc-adatok = vonalak.collect (Gyűjtők.csatlakozás ("\ n")); vonalak.zár (); Assert.assertEquals (vártData, data.trim ()); }

A Stream használatát olyan IO csatornákkal, mint a fájlműveletek, kifejezetten le kell zárnunk a streamot a Bezárás() módszer.

Mint láthatjuk, a Fájlok Az API egy másik egyszerű módot kínál a fájl tartalmának a Húr.

A következő szakaszokban vessünk egy pillantást a fájl olvasásának más, kevésbé elterjedt módszereire, amelyek bizonyos helyzetekben megfelelőek lehetnek.

6. Olvasás vele Scanner

Ezután használjuk a Scanner hogy elolvassa a Fájlból. Itt a szóközöket használjuk elválasztóként:

@Test public void, amikor aReadWithScanner_thenCorrect () dobja az IOException {String file = "src / test / resources / fileTest.txt" parancsot; Szkenner szkenner = új Szkenner (új Fájl (fájl)); scanner.useDelimiter (""); assertTrue (szkenner.hasNext ()); assertEquals ("Hello,", scanner.next ()); assertEquals ("világ!", scanner.next ()); scanner.close (); }

Ne feledje, hogy az alapértelmezett elválasztó a szóköz, de az a-val több elválasztó is használható Scanner.

A Scanner osztály akkor hasznos, ha tartalmat olvas a konzolról, vagy ha a tartalom primitív értékeket tartalmaz, ismert határolóval (pl .: egész számok szóközzel elválasztva).

7. Olvasás vele StreamTokenizer

Ezután olvassuk el a szöveges fájlt tokenekké az a használatával StreamTokenizer.

A tokenizer működése - először is meg kell találnunk, mi a következő token - String vagy szám; azt tesszük, hogy megnézzük a tokenizer.ttype terület.

Ezután elolvassuk a tényleges tokent az ilyen típus alapján:

  • tokenizer.nval - ha a típus szám volt
  • tokenizer.sval - ha a típus String volt

Ebben a példában egy másik bemeneti fájlt fogunk használni, amely egyszerűen a következőket tartalmazza:

Helló 1

A következő kód beolvassa a fájlból a karakterláncot és a számot is:

@Test public void whenReadWithStreamTokenizer_thenCorrectTokens () dobja az IOException {String file = "src / test / resources / fileTestTokenizer.txt" parancsot; FileReader olvasó = new FileReader (fájl); StreamTokenizer tokenizer = új StreamTokenizer (olvasó); // token 1 tokenizer.nextToken (); assertEquals (StreamTokenizer.TT_WORD, tokenizer.ttype); assertEquals ("Hello", 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); olvasó.zárja (); }

Vegye figyelembe, hogy a fájl token végét hogyan használják a végén.

Ez a megközelítés hasznos egy bemeneti adatfolyam tokenekké történő elemzéséhez.

8. Olvasás vele DataInputStream

Tudjuk használni DataInputStream hogy bináris vagy primitív adattípust olvasson egy fájlból.

A következő teszt beolvassa a fájlt a segítségével DataInputStream:

@Test public void, amikorReadWithDataInputStream_thenCorrect () dobja az IOException-t {String várhatóValue = "Helló, világ!"; String fájl; Karakterlánc eredménye = null; DataInputStream olvasó = new DataInputStream (új FileInputStream (fájl)); int nBytesToRead = olvasó.elérhető (); if (nBytesToRead> 0) {byte [] bytees = új byte [nBytesToRead]; olvasó.olvasott (bájt); eredmény = új karakterlánc (bájt); } assertEquals (várható érték, eredmény); }

9. Olvasás vele FileChannel

Ha nagy fájlt olvasunk, FileChannel gyorsabb lehet, mint a szokásos IO.

A következő kód a fájl segítségével olvassa el az adat bájtjait a fájlból FileChannel és RandomAccessFile:

@Test public void, amikorReadWithFileChannel_thenCorrect () dobja az IOException-t {String várható_érték = "Helló, világ!"; Karakterláncfájl = "src / test / resources / fileTest.txt"; RandomAccessFile reader = új RandomAccessFile (fájl, "r"); FileChannel csatorna = reader.getChannel (); int bufferSize = 1024; if (bufferSize> channel.size ()) {bufferSize = (int) channel.size (); } ByteBuffer buff = ByteBuffer.allocate (bufferSize); csatorna.olvasott (buff); buff.flip (); assertEquals (várható_érték, új String (buff.array ())); csatorna.zár (); olvasó.zárja (); }

10. UTF-8 kódolású fájl olvasása

Most nézzük meg, hogyan lehet egy UTF-8 kódolású fájlt olvasni BufferedReader. Ebben a példában egy kínai karaktereket tartalmazó fájlt fogunk olvasni:

@Test public void whenReadUTFEncodedFile_thenCorrect () dobja az IOException {String várható_érték = "青 空"; Karakterláncfájl = "src / test / resources / fileTestUtf8.txt"; BufferedReader reader = új BufferedReader (új InputStreamReader (új FileInputStream (fájl), "UTF-8")); String currentLine = olvasó.readLine (); olvasó.zárja (); assertEquals (várható_érték, currentLine); }

11. Tartalom olvasása URL-ről

A tartalom URL-ből történő olvasásához a „/”URL a példánkban:

@Test public void givenURLName_whenUsingURL_thenFileData () {String várhatóData = "Baeldung"; URL urlObject = új URL ("/"); URLConnection urlConnection = urlObject.openConnection (); InputStream inputStream = urlConnection.getInputStream (); Karakterlánc-adatok = readFromInputStream (inputStream); Assert.assertThat (adatok, tartalmazString (vártData)); }

Az URL-hez való csatlakozásnak vannak alternatív módjai is. Itt használtuk a URL és URLConnection osztály elérhető a standard SDK-ban.

12. Fájl elolvasása JAR-ból

A JAR fájlban található fájl elolvasásához szükségünk lesz egy JAR-ra, amelyben egy fájl található. Példánknak ezt olvassuk:LICENC.txt" tól "hamcrest-library-1.3.jar”Fájl:

@Test public void givenFileName_whenUsingJarFile_thenFileData () {String várhatóData = "BSD licenc"; Class clazz = Matchers.class; InputStream inputStream = clazz.getResourceAsStream ("/ LICENSE.txt"); Karakterlánc-adatok = readFromInputStream (inputStream); Assert.assertThat (adatok, tartalmazString (vártData)); }

Itt szeretnénk betölteni LICENC.txt amely a Hamcrest könyvtárban található, ezért a Matcher osztály, amely segít egy erőforrás megszerzésében. Ugyanaz a fájl betölthető az classloader segítségével is.

13. Következtetés

Mint láthatja, sok lehetőség van egy fájl betöltésére és az adatok leolvasására a sima Java használatával.

Fájlokat különféle helyekről tölthet be, például classpath, URL vagy jar fájlokat.

Akkor használhatja BufferedReader sorról sorra olvasni, Scanner olvasni különböző elválasztókkal, StreamTokenizer fájlokat tokenekké olvasni, DataInputStream bináris adatok és primitív adattípusok olvasása, SequenceInput Stream több fájl összekapcsolása egy adatfolyamba, FileChannel gyorsabb olvasás nagy fájlokból stb.

A forráskódot a következő GitHub repóban találja meg.