Как скопировать файл в банку за пределы банки?

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

EDIT : Я хочу, чтобы копирование файла выполнялось с помощью программы, а не вручную.

    Прежде всего, я хочу сказать, что некоторые ответы, опубликованные ранее, полностью верны, но я хочу дать свое, поскольку иногда мы не можем использовать библиотеки с открытым исходным кодом под GPL или потому, что нам слишком ленив, чтобы загрузить jar XD или что когда-либо ваша причина здесь является автономным решением.

    Функция ниже копирует ресурс рядом с файлом Jar:

      /** * Export a resource embedded into a Jar file to the local file path. * * @param resourceName ie.: "/SmartLibrary.dll" * @return The path to the exported resource * @throws Exception */ static public String ExportResource(String resourceName) throws Exception { InputStream stream = null; OutputStream resStreamOut = null; String jarFolder; try { stream = ExecutingClass.class.getResourceAsStream(resourceName);//note that each / is a directory down in the "jar tree" been the jar the root of the tree if(stream == null) { throw new Exception("Cannot get resource \"" + resourceName + "\" from Jar file."); } int readBytes; byte[] buffer = new byte[4096]; jarFolder = new File(ExecutingClass.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath()).getParentFile().getPath().replace('\\', '/'); resStreamOut = new FileOutputStream(jarFolder + resourceName); while ((readBytes = stream.read(buffer)) > 0) { resStreamOut.write(buffer, 0, readBytes); } } catch (Exception ex) { throw ex; } finally { stream.close(); resStreamOut.close(); } return jarFolder + resourceName; } 

    Просто измените ExecutingClass на имя своего classа и вызовите его следующим образом:

     String fullPath = ExportResource("/myresource.ext"); 

    Изменить для Java 7+ (для вашего удобства)

    Как ответил GOXR3PLUS и отметил Энди Томас, вы можете добиться этого с помощью:

     Files.copy( InputStream in, Path target, CopyOption... options) 

    См. Ответ GOXR3PLUS для получения более подробной информации.

    Учитывая ваш комментарий о 0-байтных файлах, я должен предположить, что вы пытаетесь сделать это программно, и, учитывая ваши tags, вы делаете это на Java. Если это правда, просто используйте Class.getResource (), чтобы получить URL-адрес, указывающий на файл в JAR, а затем Apache Commons IO FileUtils.copyURLToFile (), чтобы скопировать его в файловую систему. Например:

     URL inputUrl = getClass().getResource("/absolute/path/of/source/in/jar/file"); File dest = new File("/path/to/destination/file"); FileUtils.copyURLToFile(inputUrl, dest); 

    Скорее всего, проблема с любым кодом, который у вас есть сейчас, заключается в том, что вы (правильно) используете буферный выходной stream для записи в файл, но (неправильно) не смогли его закрыть.

    О, и вы должны отредактировать свой вопрос, чтобы точно определить, как вы хотите это сделать (программно, а не, язык, …)

    Java 8 (на самом деле FileSystem существует с 1,7) поставляется с некоторыми classными новыми classами / методами для решения этой проблемы. Поскольку кто-то уже упоминал, что JAR в основном ZIP-файл, вы можете использовать

     final URI jarFileUril = URI.create("jar:file:" + file.toURI().getPath()); final FileSystem fs = FileSystems.newFileSystem(jarFileUri, env); 

    (См. Zip-файл )

    Затем вы можете использовать один из удобных методов:

     fs.getPath("filename"); 

    Затем вы можете использовать class «Файлы»

     try (final Stream sources = Files.walk(from)) { sources.forEach(src -> { final Path dest = to.resolve(from.relativize(src).toString()); try { if (Files.isDirectory(from)) { if (Files.notExists(to)) { log.trace("Creating directory {}", to); Files.createDirectories(to); } } else { log.trace("Extracting file {} to {}", from, to); Files.copy(from, to, StandardCopyOption.REPLACE_EXISTING); } } catch (IOException e) { throw new RuntimeException("Failed to unzip file.", e); } }); } 

    Примечание. Я попытался распаковать файлы JAR для тестирования

    Более быстрый способ сделать это с помощью Java 7+ , плюс код для получения текущего каталога:

      /** * Copy a file from source to destination. * * @param source * the source * @param destination * the destination * @return True if succeeded , False if not */ public static boolean copy(InputStream source , String destination) { boolean succeess = true; System.out.println("Copying ->" + source + "\n\tto ->" + destination); try { Files.copy(source, Paths.get(destination), StandardCopyOption.REPLACE_EXISTING); } catch (IOException ex) { logger.log(Level.WARNING, "", ex); succeess = false; } return succeess; } 

    Тестирование ( icon.png – изображение внутри изображения пакета приложения):

     copy(getClass().getResourceAsStream("/image/icon.png"),getBasePathForClass(Main.class)+"icon.png"); 

    О строке кода ( getBasePathForClass(Main.class) ): -> проверить ответ, который я добавил здесь 🙂 -> Получение текущего рабочего каталога в Java

    Используйте class JarInputStream :

     // assuming you already have an InputStream to the jar file.. JarInputStream jis = new JarInputStream( is ); // get the first entry JarEntry entry = jis.getNextEntry(); // we will loop through all the entries in the jar file while ( entry != null ) { // test the entry.getName() against whatever you are looking for, etc if ( matches ) { // read from the JarInputStream until the read method returns -1 // ... // do what ever you want with the read output // ... // if you only care about one file, break here } // get the next entry entry = jis.getNextEntry(); } jis.close(); 

    См. Также: JarEntry

    Чтобы скопировать файл из своей банки, снаружи, вам необходимо использовать следующий подход:

    1. Получите InputStream в файл внутри вашего файла jar, используя getResourceAsStream()
    2. Мы открываем целевой файл с помощью FileOutputStream
    3. Мы копируем байты из ввода в выходной stream
    4. Мы закрываем streamи для предотвращения утечек ресурсов

    Пример кода, который также содержит переменную, чтобы не заменять существующие значения:

     public File saveResource(String name) throws IOException { return saveResource(name, true); } public File saveResource(String name, boolean replace) throws IOException { return saveResource(new File("."), name, replace) } public File saveResource(File outputDirectory, String name) throws IOException { return saveResource(outputDirectory, name, true); } public File saveResource(File outputDirectory, String name, boolean replace) throws IOException { File out = new File(outputDirectory, name); if (!replace && out.exists()) return out; // Step 1: InputStream resource = this.getClass().getResourceAsStream(name); if (resource == null) throw new FileNotFoundException(name + " (resource not found)"); // Step 2 and automatic step 4 try(InputStream in = resource; OutputStream writer = new BufferedOutputStream( new FileOutputStream(out))) { // Step 3 byte[] buffer = new byte[1024 * 4]; int length; while((length = in.read(buffer)) >= 0) { writer.write(buffer, 0, length); } } return out; } 

    Банкомат – это просто zip-файл. Разархивируйте его (используя любой удобный вам способ) и скопируйте файл в обычном режиме.

     ${JAVA_HOME}/bin/jar -cvf /path/to.jar 
    Давайте будем гением компьютера.