Каталог копии из файла банки

Я недавно разработал приложение и создал файл банки.

Один из моих классов создает выходной каталог, заполняя его с файлами от его ресурса.

Мой код - что-то вроде этого:

// Copy files from dir "template" in this class resource to output.
private void createOutput(File output) throws IOException {

    File template = new File(FileHelper.URL2Path(getClass().getResource("template")));
    FileHelper.copyDirectory(template, output);
}

К сожалению, это не работает.

Я попробовал следующее без удачи:

  • Используя Потоки для решения подобного материала на других классах, но это не работает с кодом директоров, было подобно http://www.exampledepot.com/egs/java.io/CopyFile.html

  • Создание шаблона File с new File(getClass().getResource("template").toUri())

При записи этого я думал о вместо того, чтобы иметь шаблонный dir в пути ресурса, имеющем zip-файл его. При выполнении его этот путь я мог получить файл как inputStream и разархивировать его, где я должен. Но я не уверен, является ли это корректный путь.

32
задан Michael Petrotta 21 August 2012 в 06:01
поделиться

4 ответа

Я думаю, что ваш подход к использованию zip-файла имеет смысл. Предположительно, вы выполните getResourceAsStream , чтобы получить доступ к внутренней части zip-архива, который логически будет выглядеть как дерево каталогов.

Скелетный подход:

InputStream is = getClass().getResourceAsStream("my_embedded_file.zip");
ZipInputStream zis = new ZipInputStream(is);
ZipEntry entry;

while ((entry = zis.getNextEntry()) != null) {
    // do something with the entry - for example, extract the data 
}
11
ответ дан 27 November 2019 в 20:39
поделиться

Я знаю, что этот вопрос довольно стар теперь, но после попытки некоторых ответов, которые не работали и другие, которые потребовали целой библиотеки всего для одного метода, я решил соединить класс. Это не требует сторонних библиотек, и это было протестировано с Java 8. Существует четыре открытых метода: copyResourcesToTempDir, copyResourcesToDir, copyResourceDirectory и jar.

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.nio.file.Files;
import java.util.Enumeration;
import java.util.Optional;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
 * A helper to copy resources from a JAR file into a directory.
 */
public final class ResourceCopy {

    /**
     * URI prefix for JAR files.
     */
    private static final String JAR_URI_PREFIX = "jar:file:";

    /**
     * The default buffer size.
     */
    private static final int BUFFER_SIZE = 8 * 1024;

    /**
     * Copies a set of resources into a temporal directory, optionally preserving
     * the paths of the resources.
     * @param preserve Whether the files should be placed directly in the
     *  directory or the source path should be kept
     * @param paths The paths to the resources
     * @return The temporal directory
     * @throws IOException If there is an I/O error
     */
    public File copyResourcesToTempDir(final boolean preserve,
        final String... paths)
        throws IOException {
        final File parent = new File(System.getProperty("java.io.tmpdir"));
        File directory;
        do {
            directory = new File(parent, String.valueOf(System.nanoTime()));
        } while (!directory.mkdir());
        return this.copyResourcesToDir(directory, preserve, paths);
    }

    /**
     * Copies a set of resources into a directory, preserving the paths
     * and names of the resources.
     * @param directory The target directory
     * @param preserve Whether the files should be placed directly in the
     *  directory or the source path should be kept
     * @param paths The paths to the resources
     * @return The temporal directory
     * @throws IOException If there is an I/O error
     */
    public File copyResourcesToDir(final File directory, final boolean preserve,
        final String... paths) throws IOException {
        for (final String path : paths) {
            final File target;
            if (preserve) {
                target = new File(directory, path);
                target.getParentFile().mkdirs();
            } else {
                target = new File(directory, new File(path).getName());
            }
            this.writeToFile(
                Thread.currentThread()
                    .getContextClassLoader()
                    .getResourceAsStream(path),
                target
            );
        }
        return directory;
    }

    /**
     * Copies a resource directory from inside a JAR file to a target directory.
     * @param source The JAR file
     * @param path The path to the directory inside the JAR file
     * @param target The target directory
     * @throws IOException If there is an I/O error
     */
    public void copyResourceDirectory(final JarFile source, final String path,
        final File target) throws IOException {
        final Enumeration<JarEntry> entries = source.entries();
        final String newpath = String.format("%s/", path);
        while (entries.hasMoreElements()) {
            final JarEntry entry = entries.nextElement();
            if (entry.getName().startsWith(newpath) && !entry.isDirectory()) {
                final File dest =
                    new File(target, entry.getName().substring(newpath.length()));
                final File parent = dest.getParentFile();
                if (parent != null) {
                    parent.mkdirs();
                }
                this.writeToFile(source.getInputStream(entry), dest);
            }
        }
    }

    /**
     * The JAR file containing the given class.
     * @param clazz The class
     * @return The JAR file or null
     * @throws IOException If there is an I/O error
     */
    public Optional<JarFile> jar(final Class<?> clazz) throws IOException {
        final String path =
            String.format("/%s.class", clazz.getName().replace('.', '/'));
        final URL url = clazz.getResource(path);
        Optional<JarFile> optional = Optional.empty();
        if (url != null) {
            final String jar = url.toString();
            final int bang = jar.indexOf('!');
            if (jar.startsWith(ResourceCopy.JAR_URI_PREFIX) && bang != -1) {
                optional = Optional.of(
                    new JarFile(
                        jar.substring(ResourceCopy.JAR_URI_PREFIX.length(), bang)
                    )
                );
            }
        }
        return optional;
    }

    /**
     * Writes an input stream to a file.
     * @param input The input stream
     * @param target The target file
     * @throws IOException If there is an I/O error
     */
    private void writeToFile(final InputStream input, final File target)
        throws IOException {
        final OutputStream output = Files.newOutputStream(target.toPath());
        final byte[] buffer = new byte[ResourceCopy.BUFFER_SIZE];
        int length = input.read(buffer);
        while (length > 0) {
            output.write(buffer, 0, length);
            length = input.read(buffer);
        }
        input.close();
        output.close();
    }

}
0
ответ дан 27 November 2019 в 20:39
поделиться

Я не уверен, что такое FileHelper , но вы НЕ сможете копировать файлы (или каталоги) непосредственно из JAR. Использование InputStream, как вы упомянули, является правильным способом (из jar или zip-архива):

InputStream is = getClass().getResourceAsStream("file_in_jar");
OutputStream os = new FileOutputStream("dest_file");
byte[] buffer = new byte[4096];
int length;
while ((length = is.read(buffer)) > 0) {
    os.write(buffer, 0, length);
}
os.close();
is.close();

Вам нужно будет сделать вышеупомянутое (конечно, обрабатывать исключения соответствующим образом) для каждого из ваших файлов. Вы можете или не сможете (в зависимости от конфигурации развертывания) прочитать рассматриваемый файл jar как JarFile (он может быть недоступен как фактический файл, если развернут как часть нерасширенного веб-приложения, для пример). Если вы можете его прочитать, вы сможете перебирать список экземпляров JarEntry и таким образом восстанавливать структуру каталогов; в противном случае вам может потребоваться сохранить его в другом месте (в текстовом или xml-ресурсе,

3
ответ дан 27 November 2019 в 20:39
поделиться

Вы можете использовать ClassLoader для получения потока к ресурсу . После того, как вы получили InputStream, вы можете считать и записать содержимое потока в OutputStream.

В вашем случае вам нужно будет создать несколько экземпляров OutputStream, по одному для каждого файла, который вы хотите скопировать. к месту назначения. Это, конечно, требует, чтобы вы заранее знали имена файлов.

Для этой задачи предпочтительно использовать getResourceAsStream, а не getResource или getResources ().

2
ответ дан 27 November 2019 в 20:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: