将图像从JAR文件复制到外部文件夹

时间:2023-02-05 14:01:44

My file structure:

我的文件结构:

This is how it looks using netbeans project:

这是使用netbeans项目的样子:

-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

我的文件imagesCopy是我创建的文件,ImagesOrg是.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:

这是正确的目录,但是当从jar文件中使用这个程序时,我得到:

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

没有第一部分

2 个解决方案

#1


2  

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.

请注意,您必须在访问文件系统之前创建文件系统(根据Oracle Docs)。我不知道为什么这是必需的,但我们去了。

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

我已经对此进行了测试,它会将文件从您的JAR内部复制到您想要的任何位置。

#2


1  

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.

了解您无法将流(您的jar)中的源复制为文件列表。除非你想先解压缩它。我的建议是你添加一个包含图像列表的txt文件然后你读取这个文件并使用建议的代码来复制每个文件。

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

和你的listImages.txt一起使用

test.jpg

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

您应该决定是否在文本文件中放置完整路径,或者不在代码中使用。

#1


2  

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.

请注意,您必须在访问文件系统之前创建文件系统(根据Oracle Docs)。我不知道为什么这是必需的,但我们去了。

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

我已经对此进行了测试,它会将文件从您的JAR内部复制到您想要的任何位置。

#2


1  

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.

了解您无法将流(您的jar)中的源复制为文件列表。除非你想先解压缩它。我的建议是你添加一个包含图像列表的txt文件然后你读取这个文件并使用建议的代码来复制每个文件。

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

和你的listImages.txt一起使用

test.jpg

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

您应该决定是否在文本文件中放置完整路径,或者不在代码中使用。