2014-04-26 150 views
0

我试图实现一些OSGi包的“无线”更新机制。为此,我需要能够从String创建一个jar文件(基本上是由JarInputStream读取的jar文件的内容)。下面的示例代码应该说明我的需求:如何读取jar文件,将其转换为字符串并从该字符串创建新的jar文件?

   //read bundle to be copied! 
       File originalFile = new File(
         "/Users/stefan/Documents/Projects/OSGi/SimpleBundle_1.0.0.201404.jar"); 
       JarInputStream fis = new JarInputStream(new FileInputStream(originalFile)); 
       StringBuilder stringBuilder = new StringBuilder(); 
       int ch; 
       while ((ch = fis.read()) != -1) { 
        stringBuilder.append((char) ch); 
       } 

       fis.close(); 

       //Create content string 
       String content = stringBuilder.toString(); 
       if (logger.isInfoEnabled()) { 
        logger.info(content); 
       } 

       //Init new jar input stream 
       JarInputStream jarInputStream = new JarInputStream(
         new ByteArrayInputStream(content.getBytes())); 

       if (logger.isInfoEnabled()) { 
        logger.info("Save content to disc!"); 
       } 

       File newFile = new File(
         "/Users/stefan/Documents/Projects/OSGi/equinox/SimpleBundle_1.0.0.201404.jar"); 
       //Init new jar output stream 
       JarOutputStream fos = new JarOutputStream(
         new FileOutputStream(newFile)); 

       if (!newFile.exists()) { 
        newFile.createNewFile(); 
       } 

       int BUFFER_SIZE = 10240; 
       byte buffer[] = new byte[BUFFER_SIZE]; 

       while (true) { 

        int nRead = jarInputStream.read(buffer, 0, 
          buffer.length); 
        if (nRead <= 0) 
         break; 

        fos.write(buffer, 0, nRead); 
       } 

       //Write content to new jar file. 
       fos.flush(); 
       fos.close(); 
       jarInputStream.close(); 

不幸的是,创建的JAR文件是空的,并抛出一个“无效的输入文件”的错误,如果我尝试使用JD-GUI打开它。是否可以从字符串“content”创建一个jar文件?

最好的问候,并非常感谢你 斯特凡

+1

它看起来像你的代码的目的是基本上从一个文件复制字节/字符到另一个。在那种情况下,是否需要通过JarInputStream等来传递它?你不能复制文件吗? – Tim

+0

我的意图是使用OSGi Bundle API来更新某个包。为此,我需要下载新的jar文件,将其保存到光盘中,然后调用update方法并交付新的jar文件的输入流。 – user3576419

+0

但是,除非我遗漏了一些东西,否则上面代码的最终结果就是磁盘上保存的文件(当前为零长度,对吗?)。所以你不能只保存字节到磁盘,简化上面的代码? (例如,如果它是一个压缩的jar,那么你现在将它解压缩到内存中,然后将它重新解压缩到磁盘上。)简化的代码可能使它更容易找到你的问题(或者问题可能消失!)然后得到一个InputStream并传递它更新()将是下一步。 (我假设你看到了你期望的日志所产生的日志语句顺序) – Tim

回答

1

你的罐子是空的,因为你不读来自任何的JarInputStream。如果你想阅读JarInputStream,你应该迭代它的条目。如果要更改Manifest,则应跳过第一个条目,使用jarInputStream的getManifest()和JarOutputStream的构造函数,其中可以指定Manifest。基于您的代码(没有明显的变化,但普通JAR副本):

ZipEntry zipEntry = jarInputStream.getNextEntry(); 
while (zipEntry != null) { 
    fos.putNextEntry(zipEntry); 

    // Simple stream copy comes here 
    int BUFFER_SIZE = 10240; 
    byte buffer[] = new byte[BUFFER_SIZE]; 
    int l = jarInputStream.read(buffer); 
    while(l >= 0) { 
     fos.write(buffer, 0, l); 
     l = jarInputStream.read(buffer); 
    } 

    zipEntry = jarInputStream.getNextEntry(); 
} 

,如果你想在复制过程中改变JAR文件的内容(或清单条目),你只需要这个。否则,简单的InputStream和FileOutputStream将完成这项工作(如Tim所说)。

+0

非常感谢Balazs Zsoldos,你的答案确实有效。 – user3576419

相关问题