How to copy a file inside the jar to a folder outside of it?

Asked

Viewed 1,279 times

1

I put images inside a package on the project. I need at runtime to display this image in an external program (in the case of linux notify-send), this program needs the exact path of the image, so I had the idea of copying the image into the system’s temporary folder, then I get an absolute path and the external program can access the image.

The idea worked at first when running the program by Netbeans it works as desired, but when creating the file. jar and do the same test system "hood".

The code is this

public class Main {

    public File getImagem(String fileName) throws URISyntaxException {
        String arquivo = "/pacote/imagem/" + fileName;
        //o erro acontece nessa linha abaixo, ao chamar o método toURI
        return new File(getClass().getResource(arquivo).toURI());

    }

    public static void main(String[] args) throws IOException, URISyntaxException {
        String fileName = "13.jpeg";
        //caminho da imagem dentro da pasta tmp do sistema
        String imagem = System.getProperty("java.io.tmpdir") + "/" + fileName;

        //file do arquivo que será copiado para a pasta tmp do sistema
        File tmp = new File(imagem);

        //File da imagem dentro do jar
        File src = new Main().getImagem(fileName);

        //copia arquivo de dentro do jar para a pasta temporaria
        copyFile(src, tmp);

        //exibe notificação mostrando a imagem que está dentro da pasta tmp do sistema
        exibirNotificacao(imagem, "titulo", "conteudo");
    }
    public static copyFile(File src, File destino){
         //...
    }    

    public static void exibirNotificacao(String url_imagem, String titulo, String conteudo) throws IOException {
         //...
    }
}

The exception message that happens when executing the jar is this

$ ./dist/Notify.jar 
Exception in thread "main" java.lang.IllegalArgumentException: URI is not hierarchical
    at java.io.File.<init>(File.java:418)
    at pacote.Main.getImagem(Main.java:30)
    at pacote.Main.main(Main.java:43)

Solution

public InputStream getImagem(String fileName) throws URISyntaxException {
        String arquivo = "/pacote/imagem/" + fileName;
        return getClass().getResourceAsStream(arquivo);

    }

    public static void main(String[] args) throws IOException, URISyntaxException {
        String fileName = "13.jpeg";
        //caminho da imagem dentro da pasta tmp do sistema
        String destino_imagem = System.getProperty("java.io.tmpdir") + "/" + fileName;


        InputStream inputImagem = new Main().getImagem(fileName);
        OutputStream outputImagem = new FileOutputStream(destino_imagem);

        byte[] buffer = new byte[inputImagem.available()];
        inputImagem.read(buffer);
        outputImagem.write(buffer);

        if(inputImagem != null)
            inputImagem.close();
        if(outputImagem!=null)
            outputImagem.close();


        //exibe notificação mostrando a imagem que está dentro da pasta tmp do sistema
        exibirNotificacao(destino_imagem, "titulo", "conteudo");
    }

I had to deal with the exceptions but then it’s up to each one, that’s it. Thank you to @Bruno

1 answer

2


In your method of image you should use: getResourceAsStream()

InputStream input =  getClass().getResourceAsStream("/pacote/imagem/" + fileName);

When the resource (image, text file, ..) is "compressed/grouped" as a jar or any other type of package you should use the getResourceAsStream.

This is because jar is a file type, as well as zip, which groups several files together, but for the operating system it is as if it were a single file. To access a specific part you need to process the file as a stream.

Link to the method documentation

  • 1

    Vlw worked with getResourceAsStream, only an error in its answer the inputStream class cannot be instantiated, because there is no constructor, I will put in the description of the question as it was. Thank you.

  • 1

    this is how it is right InputStream input = getClass().getResourceAsStream("/pacote/imagem/" + fileName);

  • 1

    Thank you. On this machine I am without java so it was a bit to the eye! Thank goodness it worked!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.