Problema acessando arquivo dentro do JAR

4 respostas
W

Estou fazendo uma aplicação que lê um arquivo que está dentro do projeto, quando executo ele no eclipse tudo ok, mas quando exporto o projeto como JAR, ele não consegue mais ler o arquivo que antes estava lendo. A parte do código que lê o arquivo está assim:

public void configure(String filename) throws Exception {
	    File file = new File("song/" + filename);
	    
	    in = AudioSystem.getAudioInputStream(file);
	    din = null;
	    AudioFormat baseFormat = in.getFormat(); 
            ....
}

A String filename passada para o método é simplesmente o nome do arquivo(no caso teste.mp3).

O engraçado é que no Eclipse funciona mas no JAR não. Se alguém puder me ajude por favor.
Agradeço desde já.

4 Respostas

W

Um workaround seria eu colocar esse arquivo no meu sistema de arquivos, por exemplo no C:/, mas queria ler este aquivo de dentro do projeto…

W

ninguém? :cry:

B

Arquivos dentro de JARs geralmente são carregados usando Class Loaders. Fazemos isso adquirindo um objeto que representa uma classe (da classe Class), e nele invocando o método getResource(String), que leva apenas um parâmetro; o nome do recurso.

Usando o seu exemplo:

public void configure(String fileName) throws UnsupportedAudioFileException, IOException, URISyntaxException { File file = new File(getClass().getResource("songs/" + fileName).toURI()); in = AudioSystem.getAudioInputStream(file); ... }
Como o método configure(String) é um método de instância, chamamos o método getClass() para obter a classe da instância, e em seguida chamamos o método getResource(String) para adquirirmos uma URL que representa o caminho para o recurso. Como o construtor de File requer uma URI, chamamos o método toURI() no objeto retornado.

Se seu método fosse estático, poderíamos usar a literal da classe, que consiste em escrever o identificador da classe seguido de “.class”. Supondo que o nome da sua classe fosse “AudioConfigurator”, o método ficaria assim:

public static void configure(String fileName) throws UnsupportedAudioFileException, IOException, URISyntaxException { File file = new File(AudioConfigurator.class.getResource("songs/" + fileName).toURI()); in = AudioSystem.getAudioInputStream(file); ... }
Note que o caminho especificado no método é relativo, isto é, começa do diretório atual, que é o pacote no qual a classe se encontra. Você pode especificar o caminho absoluto colocando uma barra ("/") no começo da String. O diretório “/” tem nome: diretório raiz, ou root directory, ou simplesmente root.

Por exemplo, vamos supor que sua classe esteja no pacote org.seuprograma.audio. Ao chamar o método acima passando “teste.mp3” como parâmetro, a URL retornada será “/org/seuprograma/audio/songs/teste.mp3”. É aconselhavel especificar o caminho absoluto, pois assim não quebrará a estrutura dos diretórios caso você decida refatorar e mudar a classe de lugar. Ficaria assim:

File file = new File(getClass().getResource("/org/seuprograma/audio/songs/" + fileName).toURI());

Note também que você pode usar a notação dos pacotes Java para especificar um pacote:

File file = new File(getClass().getResource("org.seuprograma.audio.songs." + fileName).toURI());

E, por fim, existe outro método bastante útil, getResourceAsStream(String), que retorna o recurso como uma InputStream, ao invés de uma URL. Usando-o, podemos eliminar o File do seu código:

public void configure(String fileName) throws UnsupportedAudioFileException, IOException { in = AudioSystem.getAudioInputStream(getClass().getResourceAsStream("songs/" + fileName)); ... }

Espero que isto ajude!

W

Valeu mesmo cara!

Criado 22 de janeiro de 2010
Ultima resposta 23 de jan. de 2010
Respostas 4
Participantes 2