2009-07-24 96 views
3

我有一个罐子或战争。JarFile从* .jar或inputstream到文件?

我是读这个jar的程序员,当我在这个jar里面找到jar的时候,我希望通过programmaticaly再读一遍。

但JarFile只提供了getInputStream,我无法传递给JarFile(文件文件)的构造函数。

如何从jar中读取jar?

编辑:我想着从类加载器左右获取文件莫名其妙。

+0

尽管没有什么能够阻止你,但罐子不应该包含其他罐子。我会寻找另一种方式来实现你正试图实现的功能。 http://java.sun.com/j2se/1.5.0/docs/guide/jar/jar.html – 2009-07-24 10:39:15

+1

它在战争文件中。 – blefesd 2009-07-24 10:49:45

+0

@Nick Eclipse插件是一个反例,它们以罐子的形式提供,并且通常包含嵌套的罐子。 – 2009-07-24 11:19:47

回答

1

你可以创建文件系统的JAR文件,像

File tempFile=TempFile.createFile("newJar",".jar"); 

和写入流进去。之后,你可以建立你的jar文件(临时文件),并处理它...

忘掉它,如果程序正在运行的签名Applet/JNLP,因为你不会有权利建立在文件系统中的文件...

6

更新:对不起,这可能太晚了您的需求,但我刚刚在评论中发现了最后一个问题。所以我修改了这个例子来显示每个嵌套条目被直接复制到一个OutputStream而不需要膨胀外部罐子。

在这种情况下,OutputStreamSystem.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; 
    } 
} 
-1

递归再次使用jar文件读取新的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]); 
} 

} 
0

通常这是一个到达InputStream然后使用它的问题。这使您可以从大多数“在Web服务器上的jar中的jar”问题和类似的问题中抽象出来。

显然在这种情况下,它是JarFile.getInputStream()和JarInputStream()。