getResourceAsStream () vs FileInputStream

Próbowałem załadować plik w aplikacji webapp i otrzymywałem FileNotFound wyjątek, gdy używałem FileInputStream. Jednak, używając tej samej ścieżki, udało mi się załadować plik, kiedy to zrobiłem getResourceAsStream(). Jaka jest różnica między tymi dwiema metodami i dlaczego jedna działa, a druga nie?

Author: Roman C, 2010-02-22

6 answers

The java.io.File i działa na lokalnym systemie plików na dysku. Główną przyczyną problemu jest to, że względne ścieżki w java.io zależą od bieżącego katalogu roboczego. Czyli katalog, z którego uruchamiany jest JVM (w Twoim przypadku: serwer WWW). Może to być na przykład C:\Tomcat\bin lub coś zupełnie innego, ale dlatego Nie C:\Tomcat\webapps\contextname czy cokolwiek byś się spodziewał. W normalnym projekcie Eclipse byłoby to C:\Eclipse\workspace\projectname. Możesz dowiedzieć się o aktualnych katalog roboczy w następujący sposób:

System.out.println(new File(".").getAbsolutePath());

Jednak katalog roboczy nie jest w żaden sposób programowo sterowany. Zamiast ścieżek względnych powinieneś używać bezwzględnych ścieżek W API File. Np. C:\full\path\to\file.ext.

Nie chcesz kodować na twardo ani odgadywać ścieżki bezwzględnej w aplikacjach Java (web). To tylko problem z przenośnością(tzn. działa w systemie X, ale nie w systemie Y). Normalną praktyką jest umieszczanie tego rodzaju zasobów w classpath , lub aby dodać pełną ścieżkę do classpath (w IDE takim jak Eclipse jest to odpowiednio folder src i "build path"). W ten sposób można je chwycić za pomocą ClassLoader przez ClassLoader#getResource() lub ClassLoader#getResourceAsStream(). Jest w stanie zlokalizować pliki względem "głównego" ścieżki klasowej, jak przypadkowo się domyśliłeś. W webaplikacjach (lub innych aplikacjach, które używają wielu classloaderów) zaleca się użycie ClassLoader jako zwracanego przez Thread.currentThread().getContextClassLoader() do tego celu może również wyglądać "poza" kontekstem webapp.

Inną alternatywą w webapps jest ServletContext#getResource() i jego odpowiednika ServletContext#getResourceAsStream(). Jest w stanie uzyskać dostęp do plików znajdujących się w publicznym folderze web projektu webapp, w tym folderze /WEB-INF. ServletContext jest dostępny w servletach przez dziedziczone getServletContext() Metoda, można ją nazwać taką, jaka jest.

Zobacz też:

 259
Author: BalusC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55

getResourceAsStream jest to właściwy sposób na to, aby zrobić to dla aplikacji internetowych (jak już się nauczyłeś).

Powodem jest to, że odczyt z systemu plików nie może działać, jeśli spakujesz swoją aplikację internetową w wojnę. Jest to właściwy sposób na spakowanie aplikacji internetowej. W ten sposób jest przenośny, ponieważ nie jesteś zależny od bezwzględnej ścieżki pliku lub lokalizacji, w której zainstalowany jest serwer aplikacji.

 27
Author: duffymo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-03 13:01:10

FileInputStream załaduje ścieżkę pliku przekazaną do konstruktora jako względną z katalogu roboczego procesu Java. Zazwyczaj w kontenerze internetowym jest to coś w rodzaju folderu bin.

getResourceAsStream() spowoduje załadowanie ścieżki względnej pliku ze ścieżki klasowej aplikacji.

 14
Author: matt b,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-20 14:49:37

Klasa FileInputStream działa bezpośrednio z bazowym systemem plików. Jeśli dany plik nie jest tam fizycznie obecny, nie uda mu się go otworzyć. Metoda getResourceAsStream() działa inaczej. Próbuje zlokalizować i załadować zasób używając ClassLoader klasy, do której jest wywoływany. Umożliwia to na przykład znajdowanie zasobów osadzonych w plikach jar.

 12
Author: Dirk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-22 00:57:59

Nazwa klasy.getResourceAsStream() ładuje plik za pomocą classloadera o nazwie classname. Jeśli klasa pochodzi z pliku jar, to właśnie z niego zostanie załadowany zasób.

FileInputStream służy do odczytu pliku z systemu plików.

 7
Author: Lachlan Roche,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-22 00:59:47

Jestem tutaj, rozdzielając oba zastosowania, zaznaczając je jako plik odczytany(java.io) i Resource Read (ClassLoader.getResourceAsStream()).

Plik Read - 1. Działa na lokalnym systemie plików. 2. Próbuje zlokalizować plik żądany z bieżącego katalogu uruchomionego przez JVM jako root 3. Idealnie sprawdza się przy używaniu plików do przetwarzania w ustalonym wcześniej miejscu, np./dev / files lub C:\Data.

Resource Read - 1. Prace na ścieżce klasowej 2. Próbuje zlokalizować plik / zasób w current or parent CLASSPATH classpath. 3. Idealnie sprawdza się przy próbie załadowania plików z spakowanych plików, takich jak war lub jar.

 0
Author: Aditya Bhuyan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-01-16 10:50:47