Zastanawiam się, jaka jest różnica między Class.getResource()
i ClassLoader.getResource()
?
edycja: Chcę szczególnie wiedzieć, czy buforowanie jest zaangażowane na poziomie pliku / katalogu. Jak w „czy katalogi są buforowane w wersji Class?”
AFAIK następujące czynności powinny zasadniczo zrobić to samo, ale nie są to:
getClass().getResource()
getClass().getClassLoader().getResource()
Odkryłem to, majstrując przy kodzie generującym raporty, który tworzy nowy plik WEB-INF/classes/
z istniejącego pliku w tym katalogu. Korzystając z metody z klasy, mogłem znaleźć pliki, które były tam przy użyciu getClass().getResource()
, ale próbując pobrać nowo utworzony plik, otrzymałem pusty obiekt. Przeglądanie katalogu wyraźnie pokazuje, że jest tam nowy plik. Nazwy plików zostały poprzedzone ukośnikiem jak w „/myFile.txt”.
Z drugiej strony ClassLoader
wersja getResource()
znalazła wygenerowany plik. Z tego doświadczenia wynika, że trwa pewnego rodzaju buforowanie listy katalogów. Czy mam rację, a jeśli tak, gdzie to jest udokumentowane?
Z dokumentacji API naClass.getResource()
Znajduje zasób o podanej nazwie. Reguły wyszukiwania zasobów związanych z daną klasą są implementowane przez definiujący moduł ładujący klasę. Ta metoda deleguje się do modułu ładującego klasy tego obiektu. Jeśli ten obiekt został załadowany przez moduł ładujący klasę ładowania początkowego, metoda deleguje się do ClassLoader.getSystemResource (java.lang.String).
Dla mnie brzmi to: „Class.getResource naprawdę wywołuje funkcję getResource () własnego modułu ładującego”. Co byłoby równoznaczne z robieniem getClass().getClassLoader().getResource()
. Ale oczywiście nie jest. Czy ktoś mógłby mi pomóc w tej kwestii?
źródło
Class.getResource
może przyjąć „względną” nazwę zasobu, która jest traktowana względem pakietu klasy. Alternatywnie możesz określić „bezwzględną” nazwę zasobu, używając początkowego ukośnika. Ścieżki zasobów Classloader są zawsze uważane za absolutne.Zatem poniższe są w zasadzie równoważne:
Podobnie jak te (ale różnią się od powyższych):
źródło
this.getClass().getClassLoader().getResource("/");
zwracać null? Nie powinno to być takie samo jakthis.getClass().getClassLoader().getResource(".");
Pierwsze połączenie jest wyszukiwane względem
.class
pliku, a drugie - względem katalogu głównego ścieżki klasy.Aby debugować takie problemy, drukuję adres URL:
źródło
getClassLoader().getResource("/...")
zawsze zwracanull
- moduł ładujący klasy nie usuwa wiodącego/
elementu ze ścieżki, więc wyszukiwanie zawsze kończy się niepowodzeniem. TylkogetClass().getResource()
obsługuje uruchamianie/
jako ścieżka bezwzględna w stosunku do ścieżki klasy.Musiałem to sprawdzić w specyfikacjach:
Class.getResource (zasób String)
ClassLoader.getResource (zasób String)
Klasa getResource () - dokumentacja podaje różnicę:
źródło
Wszystkie te odpowiedzi tutaj, a także odpowiedzi na to pytanie sugerują, że ładowanie bezwzględnych adresów URL, takich jak „/foo/bar.properties”, traktowane było tak samo przez
class.getResourceAsStream(String)
iclass.getClassLoader().getResourceAsStream(String)
. Tak NIE jest, przynajmniej nie w mojej konfiguracji / wersji Tomcat (obecnie 7.0.40).Przepraszam, nie mam absolutnie żadnego satysfakcjonującego wyjaśnienia, ale wydaje mi się, że kocur robi brudne sztuczki i swoją czarną magię z modułami ładującymi klasy i powoduje różnicę. Zawsze używałem
class.getResourceAsStream(String)
w przeszłości i nie miałem żadnych problemów.PS: Tutaj też to opublikowałem
źródło
Class.getResources
pobierze zasób przez moduł ładujący klasę, który ładuje obiekt. Podczas gdyClassLoader.getResource
pobierałby zasób za pomocą określonego modułu ładującego.źródło
Próbowałem czytać z input1.txt, który był w jednym z moich pakietów wraz z klasą, która próbowała go odczytać.
Następujące prace:
Najważniejszą częścią było wywołanie,
getPath()
jeśli chcesz mieć poprawną nazwę ścieżki w formacie String. NIE UŻYWAJ,toString()
ponieważ spowoduje to dodanie dodatkowego tekstu formatującego, który CAŁKOWICIE PRZESYŁA nazwę pliku (możesz wypróbować i zobaczyć wydruk).Spędziłem 2 godziny na debugowaniu tego ... :(
źródło
FileReader
lubFileInputStream
nie może być użyty do nich dostęp. Odpowiedź jest nieprawidłowa.