Gostaria de saber qual é a diferença entre Class.getResource()
e ClassLoader.getResource()
?
editar: Quero saber especialmente se há armazenamento em cache no nível do arquivo / diretório. Como em "as listagens de diretório são armazenadas em cache na versão da classe?"
AFAIK o seguinte deve essencialmente fazer o mesmo, mas não é:
getClass().getResource()
getClass().getClassLoader().getResource()
Descobri isso ao mexer em algum código de geração de relatório que cria um novo arquivo a WEB-INF/classes/
partir de um arquivo existente nesse diretório. Ao usar o método de Class, pude encontrar arquivos que estavam lá na implantação usando getClass().getResource()
, mas ao tentar buscar o arquivo recém-criado, recebi um objeto nulo. Navegar no diretório mostra claramente que o novo arquivo está lá. Os nomes dos arquivos foram anexados com uma barra como em "/myFile.txt".
A ClassLoader
versão do, getResource()
por outro lado, encontrou o arquivo gerado. A partir dessa experiência, parece que há algum tipo de cache da listagem de diretórios em andamento. Estou certo e, em caso afirmativo, onde isso está documentado?
Nos documentos da API emClass.getResource()
Localiza um recurso com um determinado nome. As regras para pesquisar recursos associados a uma determinada classe são implementadas pelo carregador de classes que define a classe. Este método delega para o carregador de classes deste objeto. Se este objeto foi carregado pelo carregador de classes de autoinicialização, o método delega para ClassLoader.getSystemResource (java.lang.String).
Para mim, diz "Class.getResource está realmente chamando getResource () do seu próprio carregador de classe". O que seria o mesmo que fazer getClass().getClassLoader().getResource()
. Mas obviamente não é. Alguém poderia me fornecer alguma iluminação sobre este assunto?
fonte
Class.getResource
pode levar um nome de recurso "relativo", que é tratado em relação ao pacote da classe. Como alternativa, você pode especificar um nome de recurso "absoluto" usando uma barra invertida. Os caminhos de recurso do carregador de classes são sempre considerados absolutos.Portanto, o seguinte é basicamente equivalente:
E também são esses (mas são diferentes do acima):
fonte
this.getClass().getClassLoader().getResource("/");
retornar nulo? Não deve ser o mesmo quethis.getClass().getClassLoader().getResource(".");
A primeira chamada pesquisa em relação ao
.class
arquivo enquanto a última pesquisa em relação à raiz do caminho de classe.Para depurar problemas como esse, imprimo o URL:
fonte
getClassLoader().getResource("/...")
sempre retornanull
- o carregador de classes não remove a liderança/
do caminho, portanto, a pesquisa sempre falha.getClass().getResource()
Manipula apenas uma partida/
como um caminho absoluto em relação ao caminho de classe.Tinha que procurar nas especificações:
Class.getResource (recurso String)
ClassLoader.getResource (Recurso String)
A documentação getResource () da classe indica a diferença:
fonte
Todas essas respostas por aqui, bem como as respostas desta pergunta , sugerem que o carregamento de URLs absolutos, como "/foo/bar.properties", seja tratado da mesma forma por
class.getResourceAsStream(String)
eclass.getClassLoader().getResourceAsStream(String)
. Esse não é o caso, pelo menos não na minha configuração / versão do Tomcat (atualmente 7.0.40).Desculpe, não tenho absolutamente nenhuma explicação satisfatória, mas acho que o tomcat faz truques sujos e sua magia negra com os carregadores de classes e causa a diferença. Eu sempre usei
class.getResourceAsStream(String)
no passado e não tive nenhum problema.PS: Eu também postei isso aqui
fonte
Class.getResources
recuperaria o recurso pelo carregador de classes que carrega o objeto. WhileClassLoader.getResource
recuperaria o recurso usando o carregador de classe especificado.fonte
Eu tentei ler a partir do input1.txt que estava dentro de um dos meus pacotes junto com a classe que estava tentando lê-lo.
Os seguintes trabalhos:
A parte mais importante era chamar
getPath()
se você deseja o nome do caminho correto no formato String. NÃO USE,toString()
pois ele adicionará algum texto de formatação extra que TOTALMENTE ENCONTRARÁ com o nome do arquivo (você pode experimentá-lo e ver a impressão).Passou 2 horas depurando isso ... :(
fonte
FileReader
ouFileInputStream
não podem ser usados para acessá-los. A resposta não está correta.