Como copiar um arquivo de um jar executável para um diretório no computador?

Olá a todos!

Estou desenvolvendo um programa para copiar um arquivo que eu coloquei dentro do meu projeto para o computador que ele for executado.
Quando rodo o programa dentro da IDE ele funciona OK! Contudo, quando gero um .jar ele não funciona.

Pelo o erro que aparece creio que o “path” esteja errado, mas não sei como fazer funcionar. A Imagem do erro está em anexo.

O meu código para achar o path do arquivo é esse:

getClass().getResource("/resources/teste.txt").getPath();

Obrigado.

Tenta usar o getResourceAsStream

Olá furutani,

Obrigado pela ajuda, mas surgiu uma dúvida,
Como vou transformar um “Stream” em um “File”? No meu programa eu faço assim:

[code]String sourcePath = getClass().getResource("/resources/teste.txt").getPath();

File file1 = new File(sourcePath);[/code]

Só que com o método getResourceAsStream não tem o “getPath()”.

Obrigado,
Filipe.

Trabalhe com FileInputStream e FileOutputStream para fazer a cópia de um lugar para outro.
Se esperar até amanhã a tarde, posto um método que faz isso.

Olá Viny,

Obrigado, mas eu já tenho o método. É o path que ta errado, pela IDE funciona normal mas quando transforma em um .jar o path muda.

Veja meu código para fazer a cópia:

@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		
		String sourcePath = getClass().getResource("/resources/teste.txt").getPath();
		
		File file1 = new File(sourcePath);
		File file2 = new File("C:\\abc");
		
		try {
			FileUtils.copyFileToDirectory(file1, file2);
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

	}

Se puder dar uma olhada na imagem do erro acho que irá entender melhor…

Grato,
Filipe.

É porque um resource dentro de um .jar não pode ser tratado como se fosse um File.

Na sua FileUtils, não tem um método que copia um Stream para outro Stream?

Essa FileUtils é da biblioteca da Apache Commons IO.

Então pelo jeito terei que mudar o jeito de fazer isso…
Obrigado.

Use o método copyInputStreamToFile:

@Override
public void actionPerformed(ActionEvent e) {
    InputStream source = getClass().getResourceAsStream("/resources/teste.txt");	
    File file = new File("C:\\teste.txt");
		
    try {
        FileUtils.copyInputStreamToFile(source, file);
    } catch (IOException e1) {
        throw new RuntimeException(e1);
    }
}

Viny,

Obrigado. Este método deixa apenas sobreescrever um arquivo já existente, e não copiar um arquivo novo para um diretório no qual ele não exista… e não existe um método para fazer isso, tipo: “copyInputStreamToDirectory”.

Contudo, acho que posso usar esse metódo mesmo, já que na aplicação real o arquivo que vou copiar vai substituir um já existente (é um arquivo .swf será que funciona também?).
E o melhor funcionou pelo Jar.

O código ficou assim:

@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		
		InputStream source = getClass().getResourceAsStream("/resources/teste.txt");
		File file = new File("C:\\abc\\teste.txt");
		
		try {
			FileUtils.copyInputStreamToFile(source, file);
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

	}

Obrigado.

Não é o que o javadoc do método diz.

Viny,

Eu testei sem o arquivo no diretório e não funcionou. Veja:

Em negrito, o destino não pode ser um diretório.

Sim, vc tem que dizer o nome do arquivo que será gerado.
O método não tem como determinar pelo Stream.

Ah sim, entendi meu erro. Não tinha colocado o nome do arquivo a ser gerado no destino. E quando coloquei pensei que tinha que ter também o arquivo no diretório.

Obrigado.

Ola, estou utilizando este metodo, porem ele copia um arquivo vazio na pasta. Sabem me dizer o q tem de errado???

public void copiar(){  
        InputStream source = getClass().getResourceAsStream("dll/Desert.jpg");  
        File file = new File("C:\\MenuPacDLL's\\Desert.jpg");  
          
        try {  
            FileUtils.copyInputStreamToFile(source, file);
        } catch (IOException e1) {  
            // TODO Auto-generated catch block  
            e1.printStackTrace();
        }
    } 

e quando chamo o metodo

BaixarPhyton copiarArquivo= new BaixarPhyton();
copiarDll.copiarArquivo();

ele ateh cria o arquivo na minha pasta MenuPacDll porem com 0kb. e quando abro a imagem nao tem imagem nenhuma :confused:

Olá augusto…

Faça o seguinte: crie um pacote no sourcepath chamado “resources” igual ao meu exemplo, coloca seu arquivo lá, na hora de criar o inputstream coloque um “/” no ínico da string conforme o meu exemplo, e faça o teste. Você pode também pra tirar a dúvida criar um destino com um nome “normal” sem o " ’ " como você fez.

[]s,
Filipe.

muito obrigado Filipe A.! topico antigo mas que salvou meu final de semana hehe