J'ai créé un fichier JAR . Maintenant, j'ai créé un autre programme Java. Je veux décompresser ce fichier JAR dans un autre répertoire, ce qui signifie que je veux faire quelque chose comme décompresser.
Si je lance jar -xf filename.jar
cela provoque une erreur:
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)`
Adaptez cet exemple: Comment extraire Java des archives JAR et Zip
Ou essayez ce code:
Extraire le contenu des fichiers Zip/JAR par programme
Supposons que
jarFile
est le fichier jar/Zip à extraire.destDir
est le chemin où il sera extrait: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();
Source : http://www.devx.com/tips/Tip/22124
Vous pouvez utiliser cet extrait de code comme référence pour effectuer votre tâche.Il est presque le même que l'extrait de code illustré ci-dessus par @JuanZe, sauf que pour ceux qui recevaient l'exception FileNotFoundException, j'ai ajouté un petit extrait de code qui vérifiera si le existe et s'il ne l'est pas, il créera le dossier parent avec les fichiers et extraira le contenu du fichier jar dans le dossier de destination spécifié.
Extrait de code:
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();
}
}
}
JarFile classe.
JarFile file = new JarFile("file.jar");
for (Enumeration<JarEntry> enum = file.entries(); enum.hasMoreElements();) {
JarEntry entry = enum.next();
System.out.println(entry.getName());
}
Voici ce que je ferais pour extraire tout mon dossier "ressources" de mon pot. Il est beaucoup plus rapide d'utiliser BufferedReader et 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;
}
Vieille question.
Voici une réponse mise à jour utilisant:
Java.nio
pour créer et copier efficacement des entréesstream
pour trier et collecter les entrées lexicographiquement (afin de toujours créer d'abord des dossiers).Notez que j'ai utilisé Java.util.Zip.ZipFile
(la classe de base) au lieu de Java.util.jar.JarFile
(la sous-classe).
Le dernier effectue plus de choses qui ne sont pas nécessaires pour "juste" extraire des fichiers d'une archive.
Cela réduit donc les frais généraux et empêche l'augmentation des exceptions liées à des problèmes de sécurité. Mais si nécessaire, vous pouvez bien sûr remplacer ZipFile/ZipEntry
par 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);
}
}
}
}
Votre titre ne semble pas très bien correspondre à la question, mais si vous voulez vraiment "écrire [a] Java extrayant un fichier jar", vous avez juste besoin Class JarFile .
Vous pouvez utiliser cette bibliothèque très simple pour emballer/décompresser le fichier jar
Très simple
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());
}
Vous pouvez également utiliser la dépendance maven
<dependency>
<groupId>fr.stevecohen.jarmanager</groupId>
<artifactId>JarManager</artifactId>
<version>0.5.0</version>
</dependency>
Vous avez également besoin de mon référentiel
<repository>
<id>repo-reapersoon</id>
<name>ReaperSoon's repo</name>
<url>http://repo-maven.stevecohen.fr</url>
</repository>
Vérifiez la dernière version avec le lien ci-dessous pour utiliser la dernière dépendance
Veuillez utiliser mon tracker de problème public si vous trouvez des bugs
Eh bien voici ma version, en utilisant 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);
}