Предпочтительный способ загрузки ресурсов в Java
Я хотел бы знать, лучший способ загрузки ресурса в Java:
-
this.getClass().getResource() (or getResourceAsStream())
, -
Thread.currentThread().getContextClassLoader().getResource(name)
, -
System.class.getResource(name)
.
5 ответов:
разработайте решение в соответствии с тем, что вы хотите...
есть две вещи, которые
getResource
/getResourceAsStream()
получит от класса, на который он вызывается...
- загрузчика класс
- начального
так что если у вас
this.getClass().getResource("foo.txt");
он попытается загрузить foo.txt из того же пакета, что и класс "this", и с загрузчиком классов класса "this". Если вы ставите " / " впереди, то вы абсолютно ссылка на ресурс.
this.getClass().getResource("/x/y/z/foo.txt")
загрузит ресурс из загрузчика классов "this" и из пакета x.y.z (он должен быть в том же каталоге, что и классы в этом пакете).
Thread.currentThread().getContextClassLoader().getResource(name)
будет загружаться с загрузчиком класса контекста, но не будет разрешать имя в соответствии с каким-либо пакетом (он должен быть абсолютно ссылочным)
System.class.getResource(name)
загрузит ресурс с загрузчиком системного класса (он также должен быть абсолютно ссылочным, так как вы не сможете ничего положить в java.пакет lang (пакет системы).
просто взгляните на источник. Также указывает, что getResourceAsStream просто вызывает "openStream" по URL-адресу, возвращенному из getResource, и возвращает его.
Ну, это отчасти зависит от того, что вы хотите произойти, если вы на самом деле в производном классе.
например,
SuperClass
находится внутри A.jar иSubClass
находится внутри B.jar, и вы выполняете код в методе экземпляра, объявленном вSuperClass
а, гдеthis
относится к экземпляруSubClass
. Если вы используетеthis.getClass().getResource()
это будет выглядеть по отношению кSubClass
, in B.jar. Я подозреваю, что это обычно не то, что требуется.лично я бы, наверное, использовать
Foo.class.getResourceAsStream(name)
чаще всего-если вы уже знаете название ресурса, который вам нужен, и вы уверены, где он находится относительноFoo
, это самый надежный способ сделать это, ИМО.конечно, бывают времена, когда это не что Вы тоже хотите: судите каждое дело по существу. Это просто "я знаю, что этот ресурс в комплекте с этим классом" является наиболее распространенным, с которым я столкнулся.
Я ищу три места, как показано ниже. Комментарии приветствуются.
public URL getResource(String resource){ URL url ; //Try with the Thread Context Loader. ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); if(classLoader != null){ url = classLoader.getResource(resource); if(url != null){ return url; } } //Let's now try with the classloader that loaded this class. classLoader = Loader.class.getClassLoader(); if(classLoader != null){ url = classLoader.getResource(resource); if(url != null){ return url; } } //Last ditch attempt. Get the resource from the classpath. return ClassLoader.getSystemResource(resource); }
Я знаю, что это очень поздно для другого ответа, но я просто хотел поделиться тем, что помогло мне в конце. Он также будет загружать ресурсы / файлы из абсолютного пути файловой системы (а не только пути к классам).
public class ResourceLoader { public static URL getResource(String resource) { final List<ClassLoader> classLoaders = new ArrayList<ClassLoader>(); classLoaders.add(Thread.currentThread().getContextClassLoader()); classLoaders.add(ResourceLoader.class.getClassLoader()); for (ClassLoader classLoader : classLoaders) { final URL url = getResourceWith(classLoader, resource); if (url != null) { return url; } } final URL systemResource = ClassLoader.getSystemResource(resource); if (systemResource != null) { return systemResource; } else { try { return new File(resource).toURI().toURL(); } catch (MalformedURLException e) { return null; } } } private static URL getResourceWith(ClassLoader classLoader, String resource) { if (classLoader != null) { return classLoader.getResource(resource); } return null; } }
Я пробовал много способов и функций, которые предлагались выше, но они не работали в моем проекте. В любом случае я нашел решение и вот это:
try { InputStream path = this.getClass().getClassLoader().getResourceAsStream("img/left-hand.png"); img = ImageIO.read(path); } catch (IOException e) { e.printStackTrace(); }