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?
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ż:
- gdzie umieścić i jak odczytać pliki zasobów konfiguracyjnych w oparciu o servlet podanie?
- co robi servletcontext.getRealPath ( " / " ) mean and when should I use it
- zalecany sposób zapisywania przesłanych plików w aplikacji servlet
- Jak tymczasowo zapisać wygenerowany plik w aplikacji webowej opartej na serwletach
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.
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.
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
.
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.
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.
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