Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/352.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在不保存到磁盘的情况下将JarInputStream转换为JarFile?_Java_Jar - Fatal编程技术网

Java 如何在不保存到磁盘的情况下将JarInputStream转换为JarFile?

Java 如何在不保存到磁盘的情况下将JarInputStream转换为JarFile?,java,jar,Java,Jar,我有一个Servlet,用户可以上传一个.jar文件来检查它的MANIFEST.MF 我知道以下方法可行: JarInputStream in = new JarInputStream(new ByteArrayInputStream (fileItem.get())); Manifest mf = in.getManifest(); 不幸的是,getManifest()方法解析Key:Value并需要“:”(冒号+空格),一个简单的冒号是不够的。由于我使用的手机在MANIFEST.MF只有

我有一个Servlet,用户可以上传一个.jar文件来检查它的
MANIFEST.MF

我知道以下方法可行:

JarInputStream in = new JarInputStream(new ByteArrayInputStream (fileItem.get()));
Manifest mf = in.getManifest(); 
不幸的是,
getManifest()
方法解析Key:Value并需要“:”(冒号+空格),一个简单的冒号是不够的。由于我使用的手机在
MANIFEST.MF
只有冒号而没有冒号+空格的情况下也可以工作,因此我想手动提取MANIFEST.MF,但不想将文件保存在磁盘上

如果我有一个JAR文件,我可以通过以下方式解析清单:

JarFile jarFile = new JarFile(fileName);
InputStream in = jarFile.getInputStream(jarFile.getEntry("META-INF/MANIFEST.MF"));
BufferedReader br = new BufferedReader(new InputStreamReader(in));

String line;
while ((line = br.readLine()) != null) {
    String[] splitAr = line.split(":", 0);
    // ...

但不幸的是,我不知道如何将
JarInputStream
(或
ByteArrayInputStream
)转换为
JarFile
,这是标准API不支持的。构造
JarFile
的唯一方法是提供
文件
引用,并且由于API没有提供创建“特殊文件”的接口,例如由InputStream支持,因此无法解决该问题


如果您使用的是UNIX系统,您可能会设置一些方法,但会失去可移植性。

在这种情况下,我将尝试执行以下操作:

  • 使用
    getNextEntry()
    ——而不是
    getNextJarEntry()
    ,遍历jar中的所有条目!看看你是否能通过这种方式到达舱单
  • 试着使用一个更通用的
    ZipInputStream
    ,它实际上扩展了它--
    JarInputStream
    ,这样您就可以访问
    META-INF/MANIFEST.MF
    文件

您可以将清单作为字符串从输入流中读取,并自己进行解析

/**
 * Read JAR  manifest as String from input stream.
 * Like JarInputStream, assume that META-INF/MANIFEST.MF entry  should be either 
 * the first or the second entry (when preceded  by the dir META-INF/).
 */
def readManifestAsString(InputStream is) {
    def zip = new ZipInputStream(is);
    def e = zip.getNextEntry();
    if (e != null && e.getName().equalsIgnoreCase("META-INF/"))
        e =  zip.getNextEntry();  
    if (e != null && JarFile.MANIFEST_NAME.equalsIgnoreCase(e.getName())) {
        byte[] bytes = getBytes(new BufferedInputStream(zip));
        return new String(bytes, "UTF8");
     }
}

byte[] getBytes(InputStream is) {
        byte[] buffer = new byte[8192];
        ByteArrayOutputStream baos = new ByteArrayOutputStream(2048);
        int n;
        while ((n = is.read(buffer, 0, buffer.length)) != -1) {
            baos.write(buffer, 0, n);
        }
        return baos.toByteArray();
 }

JAR清单规范可以找到

不幸的是,我只访问META-INF,而不是目录中的文件<代码>公共无效解析(ZipInputStream in){try{ZipEntry ZipEntry=in.getnextry();while(in.getnextry()!=null){System.out.println(ZipEntry.getName());if(ZipEntry.getName()=“META-INF/MANIFEST.MF”){System.out.println(“WOHO”);}ZipEntry=in.getnextry();}}catch(IOException e){}使用ZIP时,您将获得两个条目:META-INF(目录),然后是META-INF/MANIFEST.MF。但是,不要使用==测试字符串是否相等,而是使用equals(“META-INF/MANIFEST.MF”)!事实上,我建议只使用equalsIgnoreCase()进行测试。我的parse()不是“降序”到META-INF,它只是给出META-INF,而不是其中的MANIFEST.MF。它正在其他目录中打印.class文件..您是在创建ZipInputStream还是将JarInputStream向下转换为ZipInputStream?那么您是否已将第一行更改为
ZipInputStream in=newzipinputstream(newbytearrayinputstream(fileItem.get())?它是ZipInputStream in=newzipinputstream(newbytearrayinputstream(fileItem.get());解析(in);
/**
 * Read JAR  manifest as String from input stream.
 * Like JarInputStream, assume that META-INF/MANIFEST.MF entry  should be either 
 * the first or the second entry (when preceded  by the dir META-INF/).
 */
def readManifestAsString(InputStream is) {
    def zip = new ZipInputStream(is);
    def e = zip.getNextEntry();
    if (e != null && e.getName().equalsIgnoreCase("META-INF/"))
        e =  zip.getNextEntry();  
    if (e != null && JarFile.MANIFEST_NAME.equalsIgnoreCase(e.getName())) {
        byte[] bytes = getBytes(new BufferedInputStream(zip));
        return new String(bytes, "UTF8");
     }
}

byte[] getBytes(InputStream is) {
        byte[] buffer = new byte[8192];
        ByteArrayOutputStream baos = new ByteArrayOutputStream(2048);
        int n;
        while ((n = is.read(buffer, 0, buffer.length)) != -1) {
            baos.write(buffer, 0, n);
        }
        return baos.toByteArray();
 }