java.io.File
I małżonki działa na lokalnym systemie plików na dysku. Główną przyczyną problemu jest to, że ścieżki względne w programie java.io
są zależne od bieżącego katalogu roboczego. To znaczy katalog, z którego uruchamiana jest maszyna JVM (w twoim przypadku: serwer WWW). Może to być na przykład C:\Tomcat\bin
coś zupełnie innego, ale tym samym nie C:\Tomcat\webapps\contextname
lub cokolwiek byś tego oczekiwał. W normalnym projekcie Eclipse to byłoby C:\Eclipse\workspace\projectname
. Możesz dowiedzieć się o aktualnym katalogu roboczym w następujący sposób:
System.out.println(new File(".").getAbsolutePath());
Jednak katalog roboczy nie jest w żaden sposób sterowany programowo. Naprawdę powinieneś preferować używanie ścieżek bezwzględnych w File
API zamiast ścieżek względnych. Np C:\full\path\to\file.ext
.
Nie chcesz na stałe kodować ani zgadywać bezwzględnej ścieżki w aplikacjach Java (internetowych). To tylko problem z przenośnością (tj. Działa w systemie X, ale nie w systemie Y). Normalną praktyką jest umieszczanie tego rodzaju zasobów w ścieżce klas lub dodawanie ich pełnej ścieżki do ścieżki klas (w środowisku IDE takim jak Eclipse jest to odpowiednio src
folder i „ścieżka budowania”). W ten sposób możesz je złapać za pomocą ClassLoader
by ClassLoader#getResource()
lub ClassLoader#getResourceAsStream()
. Jest w stanie zlokalizować pliki względem „katalogu głównego” ścieżki klas, jak przez przypadek się zorientowałeś. W aplikacjach internetowych (lub innych aplikacjach, które używają wielu programów ładujących), zaleca się użycie w tym celu ClassLoader
zwróconej przez, Thread.currentThread().getContextClassLoader()
aby można było również szukać „poza” kontekstem aplikacji internetowej.
Inną alternatywą w aplikacjach internetowych jest ServletContext#getResource()
i jego odpowiednik ServletContext#getResourceAsStream()
. Jest w stanie uzyskać dostęp do plików znajdujących się w web
folderze publicznym projektu aplikacji internetowej, w tym do /WEB-INF
folderu. Jest ServletContext
on dostępny w serwletach metodą dziedziczoną getServletContext()
, możesz go nazwać tak, jak jest.
Zobacz też:
getResourceAsStream
to właściwy sposób na zrobienie tego w przypadku aplikacji internetowych (jak już wiesz).Powodem jest to, że odczyt z systemu plików nie może działać, jeśli spakujesz swoją aplikację internetową w WAR. To jest właściwy sposób pakowania aplikacji internetowej. W ten sposób jest przenośny, ponieważ nie jesteś zależny od bezwzględnej ścieżki pliku ani lokalizacji, w której jest zainstalowany serwer aplikacji.
źródło
FileInputStream załaduje ścieżkę pliku przekazaną do konstruktora jako względną z katalogu roboczego procesu Java. Zwykle w kontenerze WWW jest to coś w rodzaju
bin
folderu.getResourceAsStream()
załaduje ścieżkę do pliku względną ze ścieżki klas aplikacji .źródło
FileInputStream
Klasa współpracuje bezpośrednio z podstawowym systemem plików. Jeśli danego pliku nie ma tam fizycznie, nie uda się go otworzyć.getResourceAsStream()
Metoda działa inaczej. Próbuje zlokalizować i załadować zasób przy użyciuClassLoader
klasy, do której jest wywoływany. Umożliwia to na przykład wyszukiwanie zasobów osadzonych wjar
plikach.źródło
jar
formacie pliku i jego konsekwencjach. A w Javie odpowiedniClassLoader
może mieć tę wiedzę, podczas gdy zwykły zFileInputStream
pewnością nie.classname.getResourceAsStream () ładuje plik za pośrednictwem modułu ładującego klasy nazwa_klasy. Jeśli klasa pochodzi z pliku jar, jest to miejsce, z którego zostanie załadowany zasób.
FileInputStream służy do odczytu pliku z systemu plików.
źródło
Jestem tutaj, oddzielając oba zastosowania, oznaczając je jako odczyt pliku (java.io) i odczyt zasobów (ClassLoader.getResourceAsStream ()).
Odczyt pliku - 1. Działa w lokalnym systemie plików. 2. Próbuje zlokalizować plik żądany z bieżącego katalogu uruchomionego JVM jako root 3. Idealnie sprawdza się w przypadku używania plików do przetwarzania w określonej lokalizacji, takiej jak / dev / files lub C: \ Data.
Odczyt zasobu - 1. Działa na ścieżce klasy. 2. Próbuje zlokalizować plik / zasób w bieżącej lub nadrzędnej ścieżce klasy modułu ładującego klasy. 3. Idealnie sprawdza się przy ładowaniu plików z plików spakowanych, takich jak war lub jar.
źródło