我创建了一个JAR文件。现在,我创建了另一个Java程序。我想在其他目录中解压缩JAR文件,这意味着我想做一些像解压缩的事情。
如果我运行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)`
适应这个例子:How to extract Java resources from JAR and zip archive
或者试试这段代码:
Extract the Contents of ZIP/JAR Files Programmatically
假设
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();
您可以使用此代码段作为参考来完成任务。它与@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();
}
}
}
JarFile类。
JarFile file = new JarFile("file.jar");
for (Enumeration<JarEntry> enum = file.entries(); enum.hasMoreElements();) {
JarEntry entry = enum.next();
System.out.println(entry.getName());
}
这是我要从jar中提取整个“resources”文件夹的方法。使用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;
}
老问题。 这是一个更新的答案使用:
java.nio
可以有效地创建和复制条目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);
}
}
}
}
你的标题似乎不能很好地匹配问题,但如果你真的想“写一个java程序提取一个jar文件”,你只需要Class JarFile。
您可以使用这个非常简单的库来打包/解压缩jar文件
非常简单
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>
使用下面的链接检查最后一个版本以使用最后一个依赖项
如果你发现一些错误,请使用我的public issue tracker
那么这是我的版本,使用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);
}