Chciałbym przeczytać zasób z mojego słoika w następujący sposób:
File file;
file = new File(getClass().getResource("/file.txt").toURI());
BufferredReader reader = new BufferedReader(new FileReader(file));
//Read the file
i działa dobrze podczas uruchamiania go w Eclipse, ale jeśli wyeksportuję go do słoika, uruchom go, pojawi się wyjątek IllegalArgumentException:
Exception in thread "Thread-2"
java.lang.IllegalArgumentException: URI is not hierarchical
i naprawdę nie wiem dlaczego, ale z pewnymi testami odkryłem, że się zmieniam
file = new File(getClass().getResource("/file.txt").toURI());
do
file = new File(getClass().getResource("/folder/file.txt").toURI());
wtedy działa odwrotnie (działa w słoiku, ale nie zaćmienie).
Korzystam z Eclipse, a folder z moim plikiem znajduje się w folderze zajęć.
getResourceAsStream
nadal jest to prostsze i bardziej przenośne rozwiązanie problemu.Odpowiedzi:
Zamiast próbować adresować zasób jako plik, po prostu poproś ClassLoader, aby zwrócił InputStream dla zasobu zamiast getResourceAsStream :
Tak długo, jak
file.txt
zasób jest dostępny w ścieżce klasy, to podejście będzie działać w ten sam sposób, niezależnie od tego, czyfile.txt
zasób znajduje się wclasses/
katalogu, czy wjar
.URI is not hierarchical
Występuje, ponieważ URI zasobu w pliku jar będzie wyglądać następująco:file:/example.jar!/file.txt
. Nie można odczytać wpisów wjar
(zip
pliku), jakby to był zwykły stary plik .Wyjaśnia to dobrze odpowiedzi na:
źródło
InputStream
istnieje (jakFile.exists()
), aby moja gra mogła powiedzieć, czy użyć domyślnego pliku, czy nie. Dzięki.getClass().getResource("**/folder**/file.txt")
tego było to, że miałem ten folder w tym samym katalogu, co mój słoik :).getResourceAsStream
zwraca null, jeśli zasób nie istnieje, więc może to być test „istnieje”.Aby uzyskać dostęp do pliku w słoiku, masz dwie opcje:
Umieść plik w strukturze katalogów pasującej do nazwy pakietu (po rozpakowaniu pliku .jar powinien on znajdować się w tym samym katalogu co plik .class), a następnie uzyskaj do niego dostęp za pomocą
getClass().getResourceAsStream("file.txt")
Umieść plik w katalogu głównym (po rozpakowaniu pliku .jar powinien on znajdować się w katalogu głównym), a następnie uzyskaj do niego dostęp za pomocą
Thread.currentThread().getContextClassLoader().getResourceAsStream("file.txt")
Pierwsza opcja może nie działać, gdy jar jest używany jako wtyczka.
źródło
Miałem wcześniej ten problem i wróciłem do awaryjnego sposobu ładowania. Zasadniczo pierwszy sposób działa w pliku .jar, a drugi sposób działa w środowisku Eclipse lub innym środowisku IDE.
źródło
Do tej pory (grudzień 2017 r.) Jest to jedyne znalezione rozwiązanie, które działa zarówno wewnątrz, jak i na zewnątrz IDE.
Użyj PathMatchingResourcePatternResolver
Uwaga: działa również w wiosennym rozruchu
W tym przykładzie czytam niektóre pliki znajdujące się w folderze src / main / resources / my_folder :
źródło
Problem polega na tym, że niektóre biblioteki stron trzecich wymagają ścieżek plików, a nie strumieni wejściowych. Większość odpowiedzi nie rozwiązuje tego problemu.
W takim przypadku jednym z obejść jest skopiowanie zawartości zasobu do pliku tymczasowego. W poniższym przykładzie użyto jUnit
TemporaryFolder
.źródło
Jeśli chcesz czytać jako plik, uważam, że nadal istnieje podobne rozwiązanie:
źródło
file:
adresem URL.Upewnij się, że pracujesz z odpowiednim separatorem. Zamieniłem wszystko
/
na ścieżce względnej naFile.separator
. Działa to dobrze w IDE, jednak nie działało w JAR kompilacji.źródło
Myślę, że powinno to również działać w java. Poniższy kod, którego używam, to kotlin.
źródło
Znalazłem poprawkę
Zamień „Main” na klasę Java, w której ją zakodowałeś. Zastąp „path” ścieżką w pliku jar.
na przykład, jeśli umieścisz plik State1.txt w pakiecie com.issac.state, a następnie wpisz ścieżkę jako „/ com / issac / state / State1”, jeśli korzystasz z systemu Linux lub Mac. Jeśli używasz systemu Windows, wpisz ścieżkę jako „\ com \ issac \ state \ State1”. Nie dodawaj rozszerzenia .txt do pliku, chyba że wystąpi wyjątek Nie znaleziono pliku.
źródło
Możesz użyć modułu ładującego, który będzie czytał ścieżkę klasy jako ścieżkę ROOT (bez „/” na początku)
źródło
Jeśli używasz wiosny, możesz użyć następującej metody, aby odczytać plik z src / main / resources:
źródło
Z jakiegoś powodu
classLoader.getResource()
zawsze zwracał wartość null, gdy wdrażałem aplikację internetową do WildFly 14. Pobieranie classLoader zgetClass().getClassLoader()
lubThread.currentThread().getContextClassLoader()
zwraca wartość null.getClass().getClassLoader()
Dokument API mówi:„Zwraca moduł ładujący klasę. Niektóre implementacje mogą używać wartości null do reprezentowania modułu ładującego klasy bootstrap. Ta metoda zwróci wartość null w takich implementacjach, jeśli ta klasa została załadowana przez moduł ładujący klasy bootstrap.”
może być, jeśli używasz WildFly, a Twoja aplikacja internetowa wypróbuje to
request.getServletContext().getResource()
zwrócił adres URL zasobu. Tutaj żądanie jest przedmiotem ServletRequest.źródło
Poniższy kod działa z Spring boot (kotlin):
źródło