Hogyan kerülhető el a Java FileNotFoundException az erőforrások betöltése során

1. Áttekintés

Ebben az oktatóanyagban egy olyan problémát tárunk fel, amely felmerülhet egy Java-alkalmazás erőforrásfájljainak olvasásakor: Futás közben az erőforrásmappa ritkán van ugyanabban a helyen a lemezen, mint a forráskódunkban.

Lássuk, hogyan engedi a Java az erőforrás fájlokhoz való hozzáférést, miután kódunkat becsomagoltuk.

2. Fájlok olvasása

Tegyük fel, hogy alkalmazásunk egy fájlt olvas be indításkor:

próbáld meg (FileReader fileReader = új FileReader ("src / main / resources / input.txt"); BufferedReader olvasó = new BufferedReader (fileReader)) {String tartalma = reader.lines () .collect (Collectors.joining (System.lineSeparator ( ))); }

Ha a fenti kódot egy IDE-ben futtatjuk, a fájl hiba nélkül töltődik be. Ez azért van, mert IDE a projekt könyvtárunkat használja aktuális munkakönyvtáraként és a src / main / resources könyvtár van, ahol az alkalmazás elolvashatja.

Tegyük fel, hogy a Maven JAR plugint használjuk a kódunk JAR-ként történő csomagolására.

Amikor a parancssoron futtatjuk:

java -jar core-java-io2.jar

A következő hibát fogjuk látni:

Kivétel a "main" szálban java.io.FileNotFoundException: src / main / resources / input.txt (Nincs ilyen fájl vagy könyvtár) a java.io.FileInputStream.open0 (Native Method) címen a java.io.FileInputStream.open (FileInputStream) .java: 195) a java.io.FileInputStream. (FileInputStream.java:138) a java.io.FileInputStream. (FileInputStream.java:93) a java.io.FileReader. (FileReader.java:58) és a com webhelyen. baeldung.resource.MyResourceLoader.loadResourceWithReader (MyResourceLoader.java:14) at com.baeldung.resource.MyResourceLoader.main (MyResourceLoader.java:37)

3. Forráskód vs fordított kód

Amikor elkészítünk egy JAR-t, az erőforrások a csomagolt műtárgyak gyökérkönyvtárába kerülnek.

Példánkban azt látjuk, hogy a forráskód beállítása megvan input.txt ban ben src / main / resources a forráskód könyvtárunkban.

A megfelelő JAR struktúrában azonban a következőket látjuk:

META-INF / MANIFEST.MF META-INF / com / com / baeldung / com / baeldung / erőforrás / META-INF / maven / META-INF / maven / com.baeldung / META-INF / maven / com.baeldung / core -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-files / pom.properties

Itt, input.txt a JAR gyökérkönyvtárában található. Tehát amikor a kód végrehajtódik, meglátjuk a FileNotFoundException.

Még akkor is, ha megváltoztattuk az utat /input.txt az eredeti kód nem tudta betölteni ezt a fájlt az erőforrások általában nem címezhetők meg fájlként a lemezen. Az erőforrás fájlok a JAR belsejébe vannak csomagolva, ezért más módon kell elérnünk őket.

4. Források

Használjuk inkább az erőforrás-betöltést a erőforrások betöltése az osztályútról meghatározott fájlhely helyett. Ez a kód csomagolásától függetlenül működik:

try (InputStream inputStream = getClass (). getResourceAsStream ("/ input.txt"); BufferedReader olvasó = new BufferedReader (új InputStreamReader (inputStream))) {String tartalma = reader.lines () .collect (Collectors.joining (Rendszer. lineSeparator ())); }

ClassLoader.getResourceAsStream () megnézi az adott erőforrás osztályútvonalát. A bevezető perjel a bemenethez getResourceAsStream () utasítja a betöltőt, hogy olvassa el az osztályútvonal aljáról. A JAR fájlunk tartalma az osztályúton található, tehát ez a módszer működik.

Az IDE jellemzően tartalmazza src / main / resources osztályúton és így megtalálja a fájlokat.

5. Következtetés

Ebben a rövid cikkben megvalósítottuk a fájlok osztályútvonal-erőforrásként történő használatát, hogy a kódunk következetesen működjön, függetlenül a csomagolástól.

Mint mindig, a példa kód elérhető a GitHubon.