Ako sa vyhnúť Java FileNotFoundException pri načítaní zdrojov

1. Prehľad

V tomto tutoriále preskúmame problém, ktorý sa môže vyskytnúť pri čítaní súborov zdrojov v aplikácii Java: Počas behu programu je priečinok prostriedkov zriedka na rovnakom mieste na disku ako v našom zdrojovom kóde.

Pozrime sa, ako nám Java umožňuje prístup k súborom zdrojov po zabalení nášho kódu.

2. Čítanie súborov

Povedzme, že naša aplikácia načíta súbor počas spustenia:

try (FileReader fileReader = new FileReader ("src / main / resources / input.txt"); BufferedReader reader = new BufferedReader (fileReader)) {String contents = reader.lines () .collect (Collectors.joining (System.lineSeparator ( ))); }

Ak spustíme vyššie uvedený kód v IDE, súbor sa načíta bez chyby. To je preto, že naše IDE používa náš adresár projektu ako svoj aktuálny pracovný adresár a src / main / resources adresár je práve tam na čítanie aplikácie.

Teraz povedzme, že na zabalenie nášho kódu do formátu JAR používame doplnok Maven JAR.

Keď ho spustíme na príkazovom riadku:

java -jar jadro-java-io2.jar

Uvidíme nasledujúcu chybu:

Výnimka vo vlákne „main“ java.io.FileNotFoundException: src / main / resources / input.txt (Žiadny takýto súbor alebo adresár) nie je k dispozícii na adrese java.io.FileInputStream.open0 (natívna metóda) na adrese java.io.FileInputStream.open (FileInputStream) .java: 195) na java.io.FileInputStream. (FileInputStream.java:138) na java.io.FileInputStream. (FileInputStream.java:93) na java.io.FileReader. (FileReader.java:58) na com. baeldung.resource.MyResourceLoader.loadResourceWithReader (MyResourceLoader.java:14) na adrese com.baeldung.resource.MyResourceLoader.main (MyResourceLoader.java:37)

3. Zdrojový kód vs Zkompilovaný kód

Keď zostavujeme súbor JAR, prostriedky sa umiestnia do koreňového adresára zabalených artefaktov.

V našom príklade vidíme nastavenie zdrojového kódu vstup.txt v src / main / resources v našom adresári zdrojových kódov.

V príslušnej štruktúre JAR však vidíme:

META-INF / MANIFEST.MF META-INF / com / com / baeldung / com / baeldung / zdroj / META-INF / maven / META-INF / maven / com.baeldung / META-INF / maven / com.baeldung / jadro -java-io-files / input.txt com / baeldung / resource / MyResourceLoader.class META-INF / maven / com.baeldung / core-java-io-files / pom.xml META-INF / maven / com.baeldung / core-java-io-súbory / pom.properties

Tu, vstup.txt je v koreňovom adresári súboru JAR. Takže keď sa kód spustí, uvidíme FileNotFoundException.

Aj keby sme zmenili cestu na /input.txt pôvodný kód nemohol načítať tento súbor ako zdroje nie sú zvyčajne adresovateľné ako súbory na disku. Súbory zdrojov sú zabalené vo vnútri súboru JAR, a preto k nim potrebujeme iný spôsob prístupu.

4. Zdroje

Namiesto toho použijeme načítanie zdrojov do načítať zdroje z cesty triedy namiesto konkrétneho umiestnenia súboru. Toto bude fungovať bez ohľadu na to, ako je zabalený kód:

try (InputStream inputStream = getClass (). getResourceAsStream ("/ input.txt"); BufferedReader reader = nový BufferedReader (nový InputStreamReader (inputStream))) {String contents = reader.lines () .collect (Collectors.joining (System. lineSeparator ())); }

ClassLoader.getResourceAsStream () pozrie sa na triednu cestu pre daný zdroj. Počiatočná lomka na vstupe do getResourceAsStream () povie nakladaču, aby čítal zo základne cesty triedy. Obsah nášho súboru JAR sa nachádza v triede, takže táto metóda funguje.

IDE zvyčajne obsahuje src / main / resources na jeho triede a teda nájde súbory.

5. Záver

V tomto rýchlom článku sme implementovali načítanie súborov ako prostriedkov triedy, aby sme umožnili nášmu kódu pracovať konzistentne bez ohľadu na to, ako bol zabalený.

Vzorový kód je ako vždy k dispozícii na GitHub.


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