我有一个jar或war文件。
我正在以编程方式读取此jar文件,当我在该jar文件中找到另一个jar文件时,我想再次以编程方式读取它。
但是JarFile仅提供getInputStream,我无法将其传递给JarFile(File file)构造函数。
如何从jar文件中读取jar文件?
编辑:我考虑从类加载器或其他方式获取文件。
我有一个jar或war文件。
我正在以编程方式读取此jar文件,当我在该jar文件中找到另一个jar文件时,我想再次以编程方式读取它。
但是JarFile仅提供getInputStream,我无法将其传递给JarFile(File file)构造函数。
如何从jar文件中读取jar文件?
编辑:我考虑从类加载器或其他方式获取文件。
更新:很抱歉这可能对您来说太晚了,但我在评论中看到了您的最后一个问题。因此,我修改了示例,以显示每个嵌套条目直接复制到OutputStream
而无需膨胀外部jar。
在这种情况下,OutputStream
是System.out
,但它可以是任何OutputStream
(例如,写入文件...)。
不需要使用临时文件。您可以使用JarInputStream
而不是JarFile
,将外部条目的InputStream
传递给构造函数,然后可以读取jar的内容。
例如:
JarFile jarFile = new JarFile(warFile);
Enumeration entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry jarEntry = (JarEntry) entries.nextElement();
if (jarEntry.getName().endsWith(".jar")) {
JarInputStream jarIS = new JarInputStream(jarFile
.getInputStream(jarEntry));
// iterate the entries, copying the contents of each nested file
// to the OutputStream
JarEntry innerEntry = jarIS.getNextJarEntry();
OutputStream out = System.out;
while (innerEntry != null) {
copyStream(jarIS, out, innerEntry);
innerEntry = jarIS.getNextJarEntry();
}
}
}
...
/**
* Read all the bytes for the current entry from the input to the output.
*/
private void copyStream(InputStream in, OutputStream out, JarEntry entry)
throws IOException {
byte[] buffer = new byte[1024 * 4];
long count = 0;
int n = 0;
long size = entry.getSize();
while (-1 != (n = in.read(buffer)) && count < size) {
out.write(buffer, 0, n);
count += n;
}
}
你可以在文件系统中创建JAR文件,类似于以下内容:
File tempFile=TempFile.createFile("newJar",".jar");
将Stream写入其中。然后,您可以构建JarFile(tempFile)并处理它...
如果程序作为未签名的applet/JNLP运行,则忘记在文件系统中创建文件的权限。
递归使用JarFile再次读取新的jar文件。例如,
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
public class JarReader {
public static void readJar(String jarName) throws IOException {
String dir = new File(jarName).getParent();
JarFile jf = new JarFile(jarName);
Enumeration<JarEntry> en = jf.entries();
while(en.hasMoreElements()) {
ZipEntry ze = (ZipEntry)en.nextElement();
if(ze.getName().endsWith(".jar")) {
readJar(dir + System.getProperty("file.separator") + ze.getName());
} else {
InputStream is = jf.getInputStream(ze);
// ... read from input stream
is.close();
System.out.println("Processed class: " + ze.getName());
}
}
}
public static void main(String[] args) throws IOException {
readJar(args[0]);
}
}