Как скопировать папку из ресурсов из jar как во время выполнения, так и в dev-env? - PullRequest
1 голос
/ 17 мая 2019

В настоящее время я делаю игру с заранее подготовленными уровнями, и сейчас я храню их в ресурсах.Я хочу решить, как извлечь папку из банки в среде разработки и разработки.

Я попытался скопировать папку, используя указанный ниже метод, и передать src как File defaultWorld = new File(GameData.class.getClassLoader().getResource("worlds/").getFile());, а пункт назначения - как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();
    }
}

Я ожидал, что описанный выше метод будет работать как для dev, так и для рабочей среды, но он выдает FileNotFoundException при открытии потока вывода файла.

Ответы [ 2 ]

1 голос
/ 17 мая 2019

Вы не можете перечислить ресурсы в банке.

Любые обходные пути, о которых вы думаете, ненадежны.

  • Никогда вызовите getFile() метод URL. не возвращает правильное имя файла;он просто возвращает путь и части запроса URL-адреса, с любым процентным выходом без изменений.Кроме того, записи jar не являются URL-адресами file:, поэтому путь к ресурсу никогда не может быть действительным именем файла, если он относится к записи jar.
  • Единственный способ составить список вещей в файле jar - это выполнить итерациювсе записи jar, но вам даже не гарантирован доступ к вашему jar, потому что ClassLoaders не гарантированно является URLClassLoaders и, как правило, не гарантирует использование jar: URL.
  • Вы не можетедаже полагаться на MyApplication.class.getProtectionDomain (). getCodeSource (), потому что getCodeSource () может возвращать ноль.

Если вы хотите скопировать несколько файлов из вашего фляги, здесьВот несколько надежных способов сделать это:

  • Жесткий код списка ресурсов, которые вы планируете скопировать.Это ваше приложение, так что вы знаете, какие файлы вы помещаете в банку.
  • Храните в своем банке один текстовый файл со списком путей к ресурсам для копирования.
  • Храните ваши ресурсыв одном zip-архиве, который встроен в ваш jar-файл, и извлеките его самостоятельно с помощью ZipInputStream , который упаковывает MyApplication.class.getResourceAsStream.
0 голосов
/ 17 мая 2019

Почему вы пытаетесь реализовать метод для копирования всего каталога в другой, если уже существует реализация для этого в Apache Commons IO?

FileUtils.copyDirectory(File src, File dst);

Кроме того, вы можете использовать эту библиотеку для копированияфайлы из JAR, просто читающие InputStream и записывающие во внешний файл:

public void extractResourceFromJar(String resource, String dstPath) {

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

    FileUtils.copyInputStreamToFile(sourceStream, destination);

}

Источники: https://commons.apache.org/proper/commons-io/javadocs/api-2.5/org/apache/commons/io/FileUtils.html

...