Как написать программу на Java, которая может извлечь файл JAR и сохранить его данные в указанном каталоге (месте)? - PullRequest
30 голосов
/ 07 октября 2009

Я создал файл JAR . Теперь я создал еще одну программу на Java. Я хочу распаковать этот JAR-файл в какой-то другой каталог, что означает, что я хочу сделать что-то вроде unzip.

Если я запускаю jar -xf filename.jar, это вызывает ошибку:

Exception in thread "main" java.io.IOException: Cannot run program "jar": 
java.io.IOException: error=2, No such file or directory
     at java.lang.ProcessBuilder.start(ProcessBuilder.java:459)
     at java.lang.Runtime.exec(Runtime.java:593)`

Ответы [ 8 ]

60 голосов
/ 07 октября 2009

Адаптируйте этот пример: Как извлечь ресурсы Java из JAR и zip-архива

Или попробуйте этот код:

Программно извлекать содержимое файлов ZIP / JAR

Предположим, jarFile - это файл jar / zip, который нужно извлечь. destDir - это путь, по которому он будет извлечен:

java.util.jar.JarFile jar = new java.util.jar.JarFile(jarFile);
java.util.Enumeration enumEntries = jar.entries();
while (enumEntries.hasMoreElements()) {
    java.util.jar.JarEntry file = (java.util.jar.JarEntry) enumEntries.nextElement();
    java.io.File f = new java.io.File(destDir + java.io.File.separator + file.getName());
    if (file.isDirectory()) { // if its a directory, create it
        f.mkdir();
        continue;
    }
    java.io.InputStream is = jar.getInputStream(file); // get the input stream
    java.io.FileOutputStream fos = new java.io.FileOutputStream(f);
    while (is.available() > 0) {  // write contents of 'is' to 'fos'
        fos.write(is.read());
    }
    fos.close();
    is.close();
}
jar.close();

Источник : http://www.devx.com/tips/Tip/22124

8 голосов
/ 26 октября 2012

Вы можете использовать этот фрагмент кода как справку для выполнения своей задачи. Он почти такой же, как фрагмент кода, показанный выше @JuanZe, за исключением того, что для тех, кто получал исключение FileNotFoundException, я добавил небольшой фрагмент кода, который будет проверьте, существует ли файл, а если нет, то он создаст родительскую папку вместе с файлами и извлечет содержимое файла jar внутри указанной целевой папки.

Фрагмент кода:

public class JarDemo {

  public static void main(String[] args) throws java.io.IOException {
    java.util.jar.JarFile jarfile = new java.util.jar.JarFile(new java.io.File("E:/sqljdbc4.jar")); //jar file path(here sqljdbc4.jar)
    java.util.Enumeration<java.util.jar.JarEntry> enu= jarfile.entries();
    while(enu.hasMoreElements())
    {
        String destdir = "E:/abc/";     //abc is my destination directory
        java.util.jar.JarEntry je = enu.nextElement();

        System.out.println(je.getName());

        java.io.File fl = new java.io.File(destdir, je.getName());
        if(!fl.exists())
        {
            fl.getParentFile().mkdirs();
            fl = new java.io.File(destdir, je.getName());
        }
        if(je.isDirectory())
        {
            continue;
        }
        java.io.InputStream is = jarfile.getInputStream(je);
        java.io.FileOutputStream fo = new java.io.FileOutputStream(fl);
        while(is.available()>0)
        {
            fo.write(is.read());
        }
        fo.close();
        is.close();
    }

  }

}
5 голосов
/ 07 октября 2009

JarFile класс.

JarFile file = new JarFile("file.jar");   
for (Enumeration<JarEntry> enum = file.entries(); enum.hasMoreElements();) {   
    JarEntry entry = enum.next();   
    System.out.println(entry.getName());   
} 
4 голосов
/ 21 июля 2014

Вот что я хотел бы сделать, чтобы извлечь всю мою папку «ресурсы» из моей банки. Это намного быстрее использовать BufferedReader и BufferedWriter.

 public static boolean extractResourcesToTempFolder() {
    try {
        //If folder exist, delete it.
        String destPath = getTempDir() + File.separator + "JToolkit" + File.separator;
        deleteDirectoryRecursive(new File(destPath));            

        JarFile jarFile = new JarFile(JToolkit.class.getProtectionDomain().getCodeSource().getLocation().getPath());
        Enumeration<JarEntry> enums = jarFile.entries();
        while (enums.hasMoreElements()) {
            JarEntry entry = enums.nextElement();
            if (entry.getName().startsWith("resources")) {
                File toWrite = new File(destPath + entry.getName());
                if (entry.isDirectory()) {
                    toWrite.mkdirs();
                    continue;
                }
                InputStream in = new BufferedInputStream(jarFile.getInputStream(entry));
                OutputStream out = new BufferedOutputStream(new FileOutputStream(toWrite));
                byte[] buffer = new byte[2048];
                for (;;) {
                    int nBytes = in.read(buffer);
                    if (nBytes <= 0) {
                        break;
                    }
                    out.write(buffer, 0, nBytes);
                }
                out.flush();
                out.close();
                in.close();
            }
            System.out.println(entry.getName());
        }
    } catch (IOException ex) {
        Logger.getLogger(Methods.class.getName()).log(Level.SEVERE, null, ex);
        return false;
    }
    return true;
}
2 голосов
/ 27 февраля 2018

Старый вопрос.
Вот обновленный ответ, используя:

  • Java 7 java.nio для эффективного создания и копирования записей
  • Java 8 stream для лексикографической сортировки и сбора записей (чтобы всегда сначала создавать папки).

Обратите внимание, что я использовал java.util.zip.ZipFile (базовый класс) вместо java.util.jar.JarFile (подкласс).
Последний выполняет больше вещей, которые не требуются для «простого» извлечения файлов из архива.
Таким образом, это снижает накладные расходы и предотвращает возникновение исключений, связанных с проблемами безопасности. Но при необходимости вы можете заменить ZipFile/ZipEntry на JarFile/JarEntry.

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

public class FileUtils {

    public static void extractArchive(Path archiveFile, Path destPath) throws IOException {

        Files.createDirectories(destPath); // create dest path folder(s)

        try (ZipFile archive = new ZipFile(archiveFile.toFile())) {

            // sort entries by name to always create folders first
            List<? extends ZipEntry> entries = archive.stream()
                                                      .sorted(Comparator.comparing(ZipEntry::getName))
                                                      .collect(Collectors.toList());

            // copy each entry in the dest path
            for (ZipEntry entry : entries) {
                Path entryDest = destPath.resolve(entry.getName());

                if (entry.isDirectory()) {
                    Files.createDirectory(entryDest);
                    continue;
                }

                Files.copy(archive.getInputStream(entry), entryDest);
            }
        }

    }
}
1 голос
/ 16 сентября 2015

Вы можете использовать эту очень простую библиотеку для упаковки / распаковки файла jar

JarManager

Очень просто

import java.io.File;
import java.util.List;

import fr.stevecohen.jarmanager.JarUnpacker;

class Test {
   JarUnpacker jarUnpacker = new JarUnpacker(); 
   File myfile = new File("./myfile.jar");
   File unpackDir = new File("./mydir");

   List<File> unpacked_files = jarUnpacker.unpack(myfile.getAbsolutePath(), unpackDir.getAbsolutePath());
}

Вы также можете использовать Зависимость maven

<dependency>
    <groupId>fr.stevecohen.jarmanager</groupId>
    <artifactId>JarManager</artifactId>
    <version>0.5.0</version>
</dependency>

Вам также нужен мой репозиторий

<repository>
    <id>repo-reapersoon</id>
    <name>ReaperSoon's repo</name>
    <url>http://repo-maven.stevecohen.fr</url>
</repository>

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

Пожалуйста, используйте мой трекер открытых сообщений , если вы обнаружите какие-либо ошибки

1 голос
/ 07 октября 2009

Ваш заголовок не очень хорошо подходит для вопроса, но если вы действительно хотите "написать [a] java-программу, извлекающую jar-файл", вам просто нужно Class JarFile .

0 голосов
/ 25 июля 2017

Ну вот моя версия, используя try-with-resources:

    try (JarFile jarFile = new JarFile(artifact.getFile())) {
        for (JarEntry entry : Collections.list(jarFile.entries())) {
            try (InputStream is = jarFile.getInputStream(entry)) {
                File file = new File(targetDir, entry.getName());
                try (FileOutputStream fos = new FileOutputStream(file)) {
                    fos.write(is.read());
                }
            }
        }
    } catch (IOException e) {
        throw new MyException(String.format(
            "Unable to open jar %s", artifact.getArtifactId()), e);
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...