简体   繁体   中英

Copying images from JAR file to a folder outside

My file structure:

This is how it looks using netbeans project:

-src
    -images
        -*.jpg
    -stock
        -*.java
-images (exact copy of -images) 

and here is my jar

-jar
    -images
        -*.jpg
    -stock
        -*.java
-images (folder is created but files don't get copied) 

My files imagesCopy is the one that I create and ImagesOrg is the one inside .jar / src

 File imagesCopy = new File("images");
 File imagesOrg = new File(URLDecoder.decode(getClass().getResource("/images").getPath()));

 if (!imagesCopy.exists()) {
            imagesCopy.mkdir();
                for(final File child : imagesOrg.listFiles()) {
                    try{
                        Files.copy(child.toPath(), Paths.get(imagesCopy.getAbsolutePath()+"/"+child.getName()), REPLACE_EXISTING);
                    }catch(Exception e){
                        System.out.println(e);
                    }
                }
        }

The problem definitely lies with:

File imagesOrg = new File(URLDecoder.decode(getClass().getResource("/images").getPath()));

When compiling it it gives me, which is the proper directory

D:\Code\build\classes\images 

which is the right directory, but when using this program from jar file I get:

D:\Code\dist\file:\D:\Code\dist\egz.jar!\images

and I assume that it should just be:

D:\Code\dist\egz.jar!\images

without that first part

Probably the simplest way to do it is like this:

public static void main(String[] args) throws URISyntaxException, IOException {
    File imagesCopy = new File("C:\\Users\\<YOURNAMEHERE>\\images");

    URI uri = ImageCopy.class.getResource("/images").toURI();
    if (!uri.toString().startsWith("file:")) {
        Map<String, String> env = new HashMap<>();
        env.put("create", "true");
        FileSystems.newFileSystem(uri, env);
    }
    Path imagesOrg = Paths.get(uri);
    System.out.println(imagesOrg);

    if (!imagesCopy.exists()) {
        imagesCopy.mkdir();
        try(DirectoryStream<Path> paths = Files.newDirectoryStream(imagesOrg)) {
            for (final Path child : paths) {
                System.out.println(child);
                try {
                    String targetPath = imagesCopy.getAbsolutePath() + File.separator + child.getFileName().toString();
                    System.out.println(targetPath);
                    Files.copy(child, Paths.get(targetPath), StandardCopyOption.REPLACE_EXISTING);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

It's not super-pretty, but it works. Might need to fiddle with the code if you have nested directories.

Note that you must create the FileSystem before accessing it (as per the Oracle Docs ). I don't know why this is required, but there we go.

I've tested this and it will copy files from inside your JAR to wherever you would like.

Here is a simple code to do it. You can adapt as you need.

package br.com.jjcampos.main;

//imports here

public class CopyImage {

    private static ClassLoader loader = CopyImage.class.getClassLoader();

    public static void main(String[] args) throws IOException {
        InputStream stream = loader.getResourceAsStream("br/com/jjcampos/images/test.jpg");

        OutputStream outputStream = 
                new FileOutputStream(new File("c:/temp/newImage.jpg"));

        int read = 0;
        byte[] bytes = new byte[1024];

        while ((read = stream.read(bytes)) != -1) {
            outputStream.write(bytes, 0, read);
        }
        outputStream.close();
    }
}

Understand that you can't copy a source from a stream (your jar) as a list of files. Unless you want to unpack it first. My suggestion is you to add a txt file with the list of your images then you read this file and use suggested code to copy each one.

Something like this:

public class CopyImage {

    private static ClassLoader loader = CopyImage.class.getClassLoader();

    public static void main(String[] args) throws IOException {
        copyImages("c:/temp/");
    }


    public static void copyImages(String pathDestiny) throws IOException{
        InputStream listOfFiles = loader
           .getResourceAsStream("br/com/jjcampos/images/listImages.txt");
        BufferedReader reader = new BufferedReader(new InputStreamReader(listOfFiles));
        String line;
        while ( (line = reader.readLine())!=null ){
            InputStream stream = loader.getResourceAsStream("br/com/jjcampos/images/" 
                                                               + line);
            OutputStream outputStream = 
                    new FileOutputStream(new File(pathDestiny + line));
            int read = 0;
            byte[] bytes = new byte[1024];
            while ((read = stream.read(bytes)) != -1) {
                outputStream.write(bytes, 0, read);
            }
            outputStream.close();
        }
    }
}

And your listImages.txt with

test.jpg

And you should decide if you put the full path on the text file or not to use in your code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM