是否有可能从Pack200创建的pack.gz文件中即时加载类(在内存中),而无需首先将其解压缩回jar中?我可以找到的所有示例都向我展示了如何将其解压缩为.jar文件,然后从.jar文件加载类。您可以使用Pack200文件而无需首先解压缩它?
回答
是的,这是可能的。 Pack200.Unpacker.unpack方法写入JarOutputStream;如果您在后台线程中这样做,则可以使用管道将新的JarOutputStream连接到JarInputStream,然后从中读取。
public JarInputStream readPackFile(Path packGzFile)
throws IOException {
PipedInputStream pipeIn = new PipedInputStream();
PipedOutputStream pipeOut = new PipedOutputStream(pipeIn);
ExecutorService executor = Executors.newSingleThreadExecutor();
Callable<Void> unpacker = new Callable<Void>() {
@Override
public Void call()
throws IOException {
try (InputStream file =
new GZIPInputStream(
new BufferedInputStream(
Files.newInputStream(packGzFile)));
JarOutputStream jarOutput = new JarOutputStream(pipeOut)) {
Pack200.newUnpacker().unpack(file, jarOutput);
return null;
} finally {
executor.shutdown();
}
}
};
executor.submit(unpacker);
return new JarInputStream(pipeIn);
}
这应该足够了。但是,仍然存在两个问题:
- 如果解包操作出现错误,您将永远不会知道它,因为ExecutorServices会抑制它们的任务'异常。
- JarInputStream和JarOutputStream(更具体地说,它们的超类,InflaterInputStream和DeflaterOutputStream)不适用于管道。这是因为关闭JarOutputStream强制调用其finish()方法,但管道另一侧的JarInputStream将永远不会读取该数据。这意味着在调用
finish()
之前几乎肯定会关闭JarInputStream,导致finish()
由于管道损坏而生成IOException。
要解决第一个问题,我们可以重写JarInputStream的close
方法来解决解包操作中的任何故障。要解决第二,我们可以在覆盖的JarOutputStream到finish()
什么都不做:
public JarInputStream readPackFile(Path packGzFile)
throws IOException {
PipedInputStream pipeIn = new PipedInputStream();
PipedOutputStream pipeOut = new PipedOutputStream(pipeIn);
class NonFinishingJarOutputStream
extends JarOutputStream {
NonFinishingJarOutputStream(OutputStream out)
throws IOException {
super(out);
}
@Override
public void finish()
throws IOException {
// Deliberately empty.
}
}
ExecutorService executor = Executors.newSingleThreadExecutor();
Callable<Void> unpacker = new Callable<Void>() {
@Override
public Void call()
throws IOException {
try (InputStream file =
new GZIPInputStream(
new BufferedInputStream(
Files.newInputStream(packGzFile)));
JarOutputStream jarOutput =
new NonFinishingJarOutputStream(pipeOut)) {
Pack200.newUnpacker().unpack(file, jarOutput);
return null;
} finally {
executor.shutdown();
}
}
};
Future<?> unpackerTask = executor.submit(unpacker);
return new JarInputStream(pipeIn) {
@Override
public void close()
throws IOException {
super.close();
try {
// If the unpack generated an exception, propagate it here.
unpackerTask.get();
} catch (ExecutionException e) {
throw new IOException(e);
} catch (InterruptedException e) {
InterruptedIOException iie = new InterruptedIOException();
iie.initCause(e);
throw iie;
}
}
};
}
这给了我一个JarInputStream,而不是JarFile。 https://stackoverflow.com/questions/16602668/creating-a-classloader-to-load-a-jar-file-from-a-byte-array似乎表明,实际上很难用JarInputStream做很多事情。 –
所有JarFile构造函数都需要一个文件。我很确定没有办法使用JarFile类没有一个。 – VGR
- 1. 在压缩文件上调用File.readlines(或同等文件)而无需先解压缩它们
- 2. 列出文件,无需解压缩和选择性解压缩
- 3. pack200可以用来压缩class文件在jdk 1.4上运行吗?
- 4. 无法解压缩使用BZip2压缩的文件
- 5. PHP可以解压缩使用.NET GZipStream类压缩的文件吗?
- 6. 使用7zip sdk压缩文件,但无法使用winrar或7zip解压缩
- 7. 使用c打包文件,以便可以解压缩到原始文件
- 8. 无法解压使用zipfile构建的压缩文件(Python)
- 9. 我可以使用VBA使用本机窗口解压缩功能解压缩文件吗?
- 10. 您可以解压缩Adobe AIR应用程序吗?
- 11. 可以打开下载的压缩文件,而不必先将它保存为文件?
- 12. 解压缩(解压缩)由.net压缩(解压缩)的文件.net system.io.compression.gzipstream
- 13. 谁可以帮我解压缩数据?我无法处理它
- 14. 检查md5的压缩文件,而不完全解压缩
- 15. 使用PHP解压缩/压缩zip文件而不依靠任何扩展
- 16. 解压缩文件
- 17. 解压缩文件
- 18. 解压缩文件用PHP
- 19. Node.js - 压缩/解压缩文件夹
- 20. 压缩解压缩的exe文件
- 21. Magick ++压缩和解压缩文件
- 22. 批处理脚本来压缩文件夹,而无需使用外部软件
- 23. 如果您使用zlib解压缩数据,会发生什么情况,但它不是首先压缩的数据?
- 24. 通过servlet传递解压缩文件,而不先在服务器上解压缩
- 25. 使用ZipFile类从多个文件的zip压缩文件解压缩文件
- 26. 如何使用命令行解压缩xip压缩文件?
- 27. 如何使用rubyzip解压缩压缩文件夹
- 28. 通过C#使用cmd来压缩和解压缩文件
- 29. 如何解压缩使用fusecompress/lzo压缩的文件?
- 30. 解组特定的XML文件,而无需解压
是的,这是经常与JWS完成。 – EJP