是否有可能從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. 閱讀zip或jar文件,而不先解壓縮它
- 3. 列出文件,無需解壓縮和選擇性解壓縮
- 4. pack200可以用來壓縮class文件在jdk 1.4上運行嗎?
- 5. 閱讀文件,而無需解壓(C++)
- 6. 壓縮文件併發送它而不保存壓縮文件
- 7. 無法解壓縮使用BZip2壓縮的文件
- 8. 閱讀壓縮文件中的文件名,而無需在PowerShell中解壓縮文件
- 9. PHP可以解壓縮使用.NET GZipStream類壓縮的文件嗎?
- 10. R正在讀取一個壓縮數據文件,而無需解壓就
- 11. 從解壓縮中獲取程序集文件版本,無需解壓縮
- 12. 可以使用lessc壓縮LESS文件而不刪除註釋?
- 13. R:使用軟件包解壓縮而不是安裝它
- 14. 使用7zip sdk壓縮文件,但無法使用winrar或7zip解壓縮
- 15. 您可以解壓縮Adobe AIR應用程序嗎?
- 16. 使用c打包文件,以便可以解壓縮到原始文件
- 17. 我可以使用VBA使用本機窗口解壓縮功能解壓縮文件嗎?
- 18. 無法解壓使用zipfile構建的壓縮文件(Python)
- 19. 壓縮文件未解壓
- 20. 可以打開下載的壓縮文件,而不必先將它保存爲文件?
- 21. 誰可以幫我解壓縮數據?我無法處理它
- 22. 解壓縮(解壓縮)由.net壓縮(解壓縮)的文件.net system.io.compression.gzipstream
- 23. 檢查md5的壓縮文件,而不完全解壓縮
- 24. 訪問壓縮文件而不解壓縮?
- 25. 使用PHP解壓縮/壓縮zip文件而不依靠任何擴展
- 26. 解壓縮文件
- 27. 解壓縮文件
- 28. 用PHP解壓縮文件
- 29. 解壓縮文件用PHP
- 30. 我們可以使用.Net 4.5庫壓縮/解壓大於4GB的文件嗎?
是的,這是經常與JWS完成。 – EJP