How to copy folder's out of resources from jar both in runtime and dev-env?

旧巷老猫 提交于 2019-12-08 03:17:20

问题


I am currently making a game which have levels which are pre-made and i currently store them in resources. I want a solution to how i can extract a folder out of a jar in production and development environment.

I have tried copying the folder by using the given method below and pass the src as File defaultWorld = new File(GameData.class.getClassLoader().getResource("worlds/").getFile()); and destination as private static File worldsDir = new File("run/worlds");

public static void copyFolder(File src, File dest) {
    try {
        if (src.isDirectory()) {
            if (!dest.exists()) {
                dest.mkdir();
            }
            String[] files = src.list();

            for (String file : files) {
                copyFolder(new File(src, file), new File(dest, file));
            }
        } else {
            try (InputStream in = new FileInputStream(src)) {
                try (OutputStream out = new FileOutputStream(dest)) {
                    byte[] buffer = new byte[1024];
                    int length;
                    //copy the file content in bytes
                    while ((length = in.read(buffer)) > 0) {
                        out.write(buffer, 0, length);
                    }
                }
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

I expected the above method to work on both dev and production env but it throws FileNotFoundException when opening file output stream.


回答1:


You cannot list resources in a jar.

Any workarounds you’re thinking of, are unreliable.

  • Never call the getFile() method of URL. It does not return a valid file name; it just returns the path and query portions of the URL, with any percent-escapes intact. Furthermore, jar entries are not file: URLs, so a resource path can never be a valid file name when it refers to a jar entry.
  • The only way to list things in a jar file is by iterating through all jar entries, but you aren’t even guaranteed to have access to your jar, because ClassLoaders are not guaranteed to be URLClassLoaders, and in general are not guaranteed to use jar: URLs.
  • You can’t even rely on MyApplication.class.getProtectionDomain().getCodeSource(), because getCodeSource() can return null.

If you want to copy multiple files from your jar, here are some reliable ways to do it:

  • Hard code the list of resources you plan to copy. It’s your application, so you know what files you’re putting in the jar.
  • Keep a single text file in your jar which contains a list of resource paths to copy.
  • Store your resources in a single zip archive which is embedded in your jar, and extract it yourself with a ZipInputStream which wraps MyApplication.class.getResourceAsStream.



回答2:


Why are you trying to implement a method to copy an entire directory to another one if there already exists an implementation for that in Apache Commons IO?

FileUtils.copyDirectory(File src, File dst);

Also, you can use this library to copy files out of a JAR just reading the InputStream and writing into an external file:

public void extractResourceFromJar(String resource, String dstPath) {

    File destination = new File(dstPath);
    InputStream sourceStream = getClass().getResourceAsStream(resource);

    FileUtils.copyInputStreamToFile(sourceStream, destination);

}

Sources: https://commons.apache.org/proper/commons-io/javadocs/api-2.5/org/apache/commons/io/FileUtils.html



来源:https://stackoverflow.com/questions/56188427/how-to-copy-folders-out-of-resources-from-jar-both-in-runtime-and-dev-env

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!