Estou carregando um arquivo de texto de dentro de um pacote em um JAR compilado do meu projeto Java. A estrutura de diretórios relevante é a seguinte:
/src/initialization/Lifepaths.txt
Meu código carrega um arquivo chamando Class::getResourceAsStream
para retornar a InputStream
.
public class Lifepaths {
public static void execute() {
System.out.println(Lifepaths.class.getClass().
getResourceAsStream("/initialization/Lifepaths.txt"));
}
private Lifepaths() {}
//This is temporary; will eventually be called from outside
public static void main(String[] args) {execute();}
}
A impressão sempre será impressa null
, não importa o que eu use. Não sei por que o que foi dito acima não funcionaria, então também tentei:
"/src/initialization/Lifepaths.txt"
"initialization/Lifepaths.txt"
"Lifepaths.txt"
Nenhum desses trabalhos. Eu li várias perguntas até agora sobre o tópico, mas nenhuma delas foi útil - geralmente, elas dizem apenas para carregar arquivos usando o caminho raiz, o que eu já estou fazendo. Isso, ou apenas carregue o arquivo do diretório atual (apenas carregue filename
), o que eu também tentei. O arquivo está sendo compilado no JAR no local apropriado com o nome apropriado.
Como eu resolvo isso?
Lifepaths.class
. Dito isto, por quegetClassLoader()
permite que funcione? (Além disso, sinta-se livre para postar uma resposta!)Lifepaths.getClass()
? Não existe esse método estático definido em Object ... #getResource(String)
. BTW - Eu sempre tive problemas para fazer com que qualquer um trabalhasse em umstatic
contexto. O problema é basicamente que o carregador de classes obtido é o destinado às classes J2SE. Você precisa obter acesso ao carregador de classes de contexto destinado ao próprio aplicativo.Respostas:
Lifepaths.class.getClass().getResourceAsStream(...)
carrega recursos usando o carregador de classes do sistema, ele obviamente falha porque não vê seus JARsLifepaths.class.getResourceAsStream(...)
carrega recursos usando o mesmo carregador de classe que carregou a classe Lifepaths e deve ter acesso aos recursos em seus JARsfonte
/
antes do seu caminho, se o arquivo estiver em um diretório diferente; por exemploinitialization/Lifepaths.txt
. Se o caminho do arquivo for o mesmo da sua classe (mas com os recursos do diretório principal), basta colocar o nome do arquivo sem nenhum/
. Por exemplo, se sua classe tiver o seguinte caminhosrc/main/java/paths/Lifepaths.java
, seu arquivo deverá ter esse caminhosrc/main/resources/paths/Lifepaths.txt
.As regras são as seguintes:
E tentar:
ao invés de
(não tenho certeza se isso faz diferença, mas o primeiro usará o ClassLoader / JAR correto, enquanto eu não tiver certeza do último)
fonte
Portanto, existem várias maneiras de obter um recurso de um jar e cada uma possui uma sintaxe ligeiramente diferente, onde o caminho precisa ser especificado de maneira diferente.
A melhor explicação que eu vi é este artigo do JavaWorld . Resumirei aqui, mas se você quiser saber mais, consulte o artigo.
Métodos
1)
ClassLoader.getResourceAsStream()
.Formato: "/" - nomes separados; sem "/" inicial (todos os nomes são absolutos).
Exemplo:
this.getClass().getClassLoader().getResourceAsStream("some/pkg/resource.properties");
2)
Class.getResourceAsStream()
Formato: "/" - nomes separados; "/" inicial indica nomes absolutos; todos os outros nomes são relativos ao pacote da classe
Exemplo:
this.getClass().getResourceAsStream("/some/pkg/resource.properties");
fonte
Não use caminhos absolutos, torne-os relativos ao diretório 'recursos' no seu projeto. Código rápido e sujo que exibe o conteúdo do MyTest.txt do diretório 'recursos'.
fonte
Você pode tentar isso para obter o fluxo, ou seja, primeiro obtenha o URL e abra-o como fluxo.
Uma vez tive uma pergunta semelhante: a leitura do arquivo txt do jar falha, mas a leitura da imagem funciona
fonte
Parece haver um problema com o ClassLoader que você está usando. Use o contextClassLoader para carregar a classe. Independentemente de estar em um método estático / não estático
Thread.currentThread().getContextClassLoader().getResourceAsStream
......fonte
Eu me encontrei em uma questão semelhante. Como estou usando o maven, precisava atualizar meu pom.xml para incluir algo como isto:
Observe a etiqueta de recurso para especificar onde está essa pasta. Se você tiver projetos aninhados (como eu), convém obter recursos de outras áreas em vez de apenas no módulo em que está trabalhando. Isso ajuda a reduzir a manutenção do mesmo arquivo em cada repositório, se você estiver usando dados de configuração semelhantes
fonte
O que funcionou para mim foi adicionar o arquivo
My Project/Java Resources/src
e usarNão precisei adicionar explicitamente esse arquivo ao caminho (adicioná-lo a
/src
isso aparentemente)fonte
Não sei se da ajuda, mas no meu caso, eu tinha meu recurso na pasta / src / e estava recebendo esse erro. Em seguida, mudei a imagem para a pasta bin e ela corrigiu o problema.
fonte
Verifique se o diretório de recursos (por exemplo, "src") está no seu caminho de classe (verifique se é um diretório de origem no caminho de construção no eclipse).
Verifique se o clazz está carregado no carregador de classe principal.
Em seguida, para carregar src / initialization / Lifepaths.txt, use
Por que:
clazz.getResourcesAsStream(foo)
procura dentro do caminho de classe do clazz , em relação ao diretório em que o clazz vive . O "/" principal faz com que seja carregado a partir da raiz de qualquer diretório no caminho de classe do clazz.A menos que você esteja em um contêiner de algum tipo, como o Tomcat, ou esteja fazendo algo diretamente com os ClassLoaders, é possível tratar apenas o caminho de classe do eclipse / linha de comando como o único caminho de classe do carregador de classes.
fonte
O carregador de classe JVM padrão usará pai-carregador de classe para carregar recursos primeiro: .
Lifepaths.class.getClass()
O classloader debootstrap classloader
, portantogetResourceAsStream
, pesquisará apenas $ JAVA_HOME, independentemente do usuário fornecidoclasspath
. Obviamente, Lifepaths.txt não está lá.Lifepaths.class
O classloader de ésystem classpath classloader
, portanto,getResourceAsStream
será pesquisado definido pelo usuárioclasspath
e Lifepaths.txt estará lá.Ao usar
java.lang.Class#getResourceAsStream(String name)
, o nome que não inicia com '/' será adicionadopackage name
como prefixo. Se você quiser evitar isso, usejava.lang.ClassLoader#getResourceAsStream
. Por exemplo:fonte
A grosso modo:
getClass().getResource("/")
~ =Thread.currentThread().getContextClassLoader().getResource(".")
Suponha que a estrutura do seu projeto seja a seguinte:
fonte
se você estiver usando o Maven, verifique se a sua embalagem é 'jar' e não 'pom'.
fonte
O que você realmente precisa é de um classPath absoluto completo para o arquivo. Portanto, em vez de adivinhar, tente descobrir o ROOT e mova o arquivo para um local melhor, com base nas estruturas de arquivos <.war> ...
fonte
O que funcionou para mim é que coloquei o arquivo em
e
fonte
src/main/JAVA
, obviamente seus arquivos que não são de código não devem estar localizados aqui.@Emracool ... eu sugiro uma alternativa. Desde que você parece estar tentando carregar um arquivo * .txt. Melhor usar
FileInputStream()
do que issogetClass().getClassLoader().getResourceAsStream()
ou irritantegetClass().getResourceAsStream()
. Pelo menos seu código será executado corretamente.fonte