Gostaria de ler um recurso de dentro do meu jar da seguinte forma:
File file;
file = new File(getClass().getResource("/file.txt").toURI());
BufferredReader reader = new BufferedReader(new FileReader(file));
//Read the file
e funciona bem ao executá-lo no Eclipse, mas se eu exportá-lo para um jar, execute-o, há uma IllegalArgumentException:
Exception in thread "Thread-2"
java.lang.IllegalArgumentException: URI is not hierarchical
e eu realmente não sei por que, mas com alguns testes descobri que se eu mudar
file = new File(getClass().getResource("/file.txt").toURI());
para
file = new File(getClass().getResource("/folder/file.txt").toURI());
então funciona o contrário (funciona em jar, mas não eclipse).
Estou usando o Eclipse e a pasta com meu arquivo está em uma pasta de classe.
getResourceAsStream
ainda é uma solução mais simples e mais portátil para o problema.Respostas:
Em vez de tentar endereçar o recurso como um arquivo, peça ao ClassLoader para retornar um InputStream para o recurso, em vez de getResourceAsStream :
Enquanto o
file.txt
recurso estiver disponível no caminho de classe, essa abordagem funcionará da mesma maneira, independentemente de ofile.txt
recurso estar em umclasses/
diretório ou dentro de umjar
.A
URI is not hierarchical
ocorre porque o URI de um recurso dentro de um arquivo jar vai ser algo como isto:file:/example.jar!/file.txt
. Você não pode ler as entradas em umjar
(umzip
arquivo) como se fosse um arquivo antigo simples .Isso é bem explicado pelas respostas para:
fonte
InputStream
existe (comoFile.exists()
) para que meu jogo possa dizer se deve usar o arquivo padrão ou não. Obrigado.getClass().getResource("**/folder**/file.txt")
ele funcionou é porque eu tinha essa pasta no mesmo diretório do meu jar :).getResourceAsStream
retorna nulo se o recurso não existir, para que possa ser o seu teste "existe".Para acessar um arquivo em um jar, você tem duas opções:
Coloque o arquivo na estrutura de diretórios que corresponde ao nome do pacote (após extrair o arquivo .jar, ele deve estar no mesmo diretório que o arquivo .class) e acesse-o usando
getClass().getResourceAsStream("file.txt")
Coloque o arquivo na raiz (depois de extrair o arquivo .jar, ele deve estar na raiz) e acesse-o usando
Thread.currentThread().getContextClassLoader().getResourceAsStream("file.txt")
A primeira opção pode não funcionar quando o jar é usado como um plug-in.
fonte
Eu já tinha esse problema e abri caminho para o carregamento. Basicamente, a primeira maneira de trabalhar no arquivo .jar e a segunda maneira funcionam no eclipse ou em outro IDE.
fonte
Até agora (dezembro de 2017), esta é a única solução que eu encontrei que funciona tanto dentro como fora do IDE.
Use PathMatchingResourcePatternResolver
Nota: também funciona em boot de mola
Neste exemplo, estou lendo alguns arquivos localizados em src / main / resources / my_folder :
fonte
O problema é que certas bibliotecas de terceiros exigem nomes de caminhos de arquivos em vez de fluxos de entrada. A maioria das respostas não aborda esse problema.
Nesse caso, uma solução alternativa é copiar o conteúdo do recurso em um arquivo temporário. O exemplo a seguir usa jUnit
TemporaryFolder
.fonte
Se você quiser ler como um arquivo, acredito que ainda exista uma solução semelhante:
fonte
file:
URL.Certifique-se de trabalhar com o separador correto. Substituí tudo
/
em um caminho relativo por aFile.separator
. Isso funcionou bem no IDE, no entanto, não funcionou no JAR de compilação.fonte
Eu acho que isso deve funcionar em java também. O código a seguir que eu uso está usando o kotlin.
fonte
Eu encontrei uma correção
Substitua "Main" pela classe java em que você o codificou. Substitua "path" pelo caminho dentro do arquivo jar.
por exemplo, se você colocar State1.txt no pacote com.issac.state, digite o caminho como "/ com / issac / state / State1" se você executar Linux ou Mac. Se você executar o Windows, digite o caminho como "\ com \ issac \ state \ State1". Não adicione a extensão .txt ao arquivo, a menos que ocorra a exceção Arquivo não encontrado.
fonte
Você pode usar o carregador de classes que lerá o caminho de classe como caminho ROOT (sem "/" no início)
fonte
Se você estiver usando o spring, poderá usar o seguinte método para ler o arquivo em src / main / resources:
fonte
Por alguma razão,
classLoader.getResource()
sempre retornava nulo quando implantei o aplicativo Web no WildFly 14. obtendo classLoader degetClass().getClassLoader()
ouThread.currentThread().getContextClassLoader()
retorna nulo.getClass().getClassLoader()
O documento da API diz:"Retorna o carregador de classes da classe. Algumas implementações podem usar null para representar o carregador de classes de inicialização. Este método retornará nulo nessas implementações se essa classe tiver sido carregada pelo carregador de classes de inicialização."
Pode ser que você esteja usando o WildFly e seu aplicativo da Web, tente isso
request.getServletContext().getResource()
retornou o URL do recurso. Aqui request é um objeto de ServletRequest.fonte
O código abaixo funciona com o Spring boot (kotlin):
fonte