Kako izbjeći Java FileNotFoundException prilikom učitavanja resursa

1. Pregled

U ovom uputstvu istražit ćemo problem koji se može pojaviti prilikom čitanja datoteka resursa u Java aplikaciji: Tijekom izvođenja mapa resursa rijetko je na istom mjestu na disku kao u našem izvornom kodu.

Pogledajmo kako nam Java omogućuje pristup datotekama resursa nakon što je naš kod spakiran.

2. Čitanje datoteka

Recimo da naša aplikacija čita datoteku tijekom pokretanja:

probajte (FileReader fileReader = novi FileReader ("src / main / resources / input.txt"); BufferedReader čitač = novi BufferedReader (fileReader)) {Sadržaj niza = reader.lines () .collect (Collectors.joining (System.lineSeparator ( ))); }

Ako gornji kôd pokrenemo u IDE-u, datoteka se učitava bez pogreške. Ovo je zbog naš IDE koristi naš direktorij projekata kao svoj trenutni radni direktorij i src / glavni / resursi direktorij je upravo tamo da ga aplikacija može pročitati.

Recimo da koristimo dodatak Maven JAR za pakiranje koda kao JAR.

Kad ga pokrenemo u naredbenom retku:

java -jar core-java-io2.jar

Vidjet ćemo sljedeću pogrešku:

Iznimka u niti "main" java.io.FileNotFoundException: src / main / resources / input.txt (Nema takve datoteke ili direktorija) na java.io.FileInputStream.open0 (Native Method) na 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 com.baeldung.resource.MyResourceLoader.main (MyResourceLoader.java:37)

3. Izvorni kod u odnosu na kompilirani kod

Kada gradimo JAR, resursi se smještaju u korijenski direktorij pakiranih artefakata.

U našem primjeru vidimo da postavljanje izvornog koda ima ulaz.txt u src / glavni / resursi u našem direktoriju izvornog koda.

Međutim, u odgovarajućoj JAR strukturi vidimo:

META-INF / MANIFEST.MF META-INF / com / com / baeldung / com / baeldung / resource / 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

Ovdje, ulaz.txt nalazi se u korijenskom direktoriju JAR-a. Dakle, kad se kod izvrši, vidjet ćemo FileNotFoundException.

Čak i ako bismo promijenili put do /input.txt izvorni kod nije mogao učitati ovu datoteku kao resursi se obično ne mogu adresirati kao datoteke na disku. Datoteke resursa su zapakirane unutar JAR-a i zato nam je potreban drugačiji način pristupa.

4. Resursi

Umjesto toga upotrijebimo učitavanje resursa za učitavanje resursa s putova predavanja umjesto određenog mjesta datoteke. To će raditi bez obzira na to kako je kôd zapakiran:

probajte (InputStream inputStream = getClass (). getResourceAsStream ("/ input.txt"); BufferedReader čitač = novi BufferedReader (novi InputStreamReader (inputStream))) {Sadržaj niza = reader.lines () .collect (Collectors.joining (System. lineSeparator ())); }

ClassLoader.getResourceAsStream () gleda put predavanja za zadani resurs. Vodeća crta na ulazu u getResourceAsStream () govori loaderu da čita s baze putopisa. Sadržaj naše JAR datoteke nalazi se na putu predavanja, tako da ova metoda djeluje.

IDE obično uključuje src / glavni / resursi na svojoj stazi i, tako, pronalazi datoteke.

5. Zaključak

U ovom smo kratkom članku implementirali učitavanje datoteka kao resursa putne staze kako bismo omogućili dosljednom radu našeg koda bez obzira na to kako je upakiran.

Kao i uvijek, primjer koda dostupan je na GitHub-u.


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