strings - Forma preferida de cargar recursos en Java
string-array android studio (5)
Me gustaría saber la mejor forma de cargar un recurso en Java:
-
this.getClass().getResource() (or getResourceAsStream())
, -
Thread.currentThread().getContextClassLoader().getResource(name)
, -
System.class.getResource(name)
.
Bueno, en parte depende de lo que quieras que pase si realmente estás en una clase derivada.
Por ejemplo, suponga que SuperClass
está en A.jar y SubClass
está en B.jar, y está ejecutando código en un método de instancia declarado en SuperClass
pero donde this
refiere a una instancia de SubClass
. Si usa this.getClass().getResource()
se verá relativo a SubClass
, en B.jar. Sospecho que generalmente no es lo que se requiere.
Personalmente, probablemente usaría Foo.class.getResourceAsStream(name)
más frecuencia: si ya sabe el nombre del recurso que está buscando, y está seguro de dónde está relacionado con Foo
, esa es la forma más robusta de haciéndolo IMO.
Por supuesto, hay momentos en que eso no es lo que quieres, también: juzga cada caso en función de sus méritos. Es solo el "Sé que este recurso está incluido con esta clase" es el más común que he encontrado.
Busco tres lugares como se muestra a continuación. Comentarios bienvenidos.
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);
}
Calcula la solución de acuerdo con lo que quieras ...
Hay dos cosas que getResource
/ getResourceAsStream()
obtendrán de la clase a la que se llama ...
- El cargador de clases
- La ubicación de partida
Entonces si lo haces
this.getClass().getResource("foo.txt");
intentará cargar foo.txt desde el mismo paquete que la clase "this" y con el cargador de clase de la clase "this". Si coloca un "/" al frente, entonces está haciendo referencia absoluta al recurso.
this.getClass().getResource("/x/y/z/foo.txt")
cargará el recurso del cargador de clases de "this" y del paquete xyz (deberá estar en el mismo directorio que las clases en ese paquete).
Thread.currentThread().getContextClassLoader().getResource(name)
se cargará con el cargador de clases de contexto, pero no resolverá el nombre de acuerdo con ningún paquete (debe estar absolutamente referenciado)
System.class.getResource(name)
Cargará el recurso con el cargador de clases del sistema (también debería tener una referencia absoluta, ya que no podrá incluir nada en el paquete java.lang (el paquete de Sistema).
Solo eche un vistazo a la fuente. También indica que getResourceAsStream solo llama a "openStream" en la URL devuelta por getResource y lo devuelve.
Intenté muchas formas y funciones que sugerí anteriormente, pero no funcionaron en mi proyecto. De todos modos, he encontrado una solución y aquí está:
try {
InputStream path = this.getClass().getClassLoader().getResourceAsStream("img/left-hand.png");
img = ImageIO.read(path);
} catch (IOException e) {
e.printStackTrace();
}
Sé que es muy tarde para otra respuesta, pero solo quería compartir lo que me ayudó al final. También cargará recursos / archivos de la ruta absoluta del sistema de archivos (no solo de la ruta de clases).
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;
}
}