如何使用java.util.jar.JarOutputStream
以編程方式創建JAR文件?我的程序生成的JAR文件看起來是正確的(它提取的很好),但是當我嘗試從它加載一個庫時,Java抱怨它找不到明確存儲在其中的文件。如果我解壓縮JAR文件並使用Sun的jar
命令行工具重新壓縮它,則生成的庫工作正常。總之,我的JAR文件出了問題。如何使用JarOutputStream創建JAR文件?
請解釋如何以編程方式創建JAR文件,並附帶清單文件。
如何使用java.util.jar.JarOutputStream
以編程方式創建JAR文件?我的程序生成的JAR文件看起來是正確的(它提取的很好),但是當我嘗試從它加載一個庫時,Java抱怨它找不到明確存儲在其中的文件。如果我解壓縮JAR文件並使用Sun的jar
命令行工具重新壓縮它,則生成的庫工作正常。總之,我的JAR文件出了問題。如何使用JarOutputStream創建JAR文件?
請解釋如何以編程方式創建JAR文件,並附帶清單文件。
事實證明,JarOutputStream
有三個無證的怪癖:
下面是創建一個JAR文件的正確方法:
public void run() throws IOException
{
Manifest manifest = new Manifest();
manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
JarOutputStream target = new JarOutputStream(new FileOutputStream("output.jar"), manifest);
add(new File("inputDirectory"), target);
target.close();
}
private void add(File source, JarOutputStream target) throws IOException
{
BufferedInputStream in = null;
try
{
if (source.isDirectory())
{
String name = source.getPath().replace("\\", "/");
if (!name.isEmpty())
{
if (!name.endsWith("/"))
name += "/";
JarEntry entry = new JarEntry(name);
entry.setTime(source.lastModified());
target.putNextEntry(entry);
target.closeEntry();
}
for (File nestedFile: source.listFiles())
add(nestedFile, target);
return;
}
JarEntry entry = new JarEntry(source.getPath().replace("\\", "/"));
entry.setTime(source.lastModified());
target.putNextEntry(entry);
in = new BufferedInputStream(new FileInputStream(source));
byte[] buffer = new byte[1024];
while (true)
{
int count = in.read(buffer);
if (count == -1)
break;
target.write(buffer, 0, count);
}
target.closeEntry();
}
finally
{
if (in != null)
in.close();
}
}
這些'怪癖'實際上是zip規範的一部分(jar文件只是帶有清單和不同擴展名的zip文件)。我同意它應該記錄在API文檔中,但是 - 我建議打開一個問題(http://bugs.sun.com/bugdatabase/) – 2009-08-15 19:18:03
更重要的是,API應該可以防止你通過創建無效的ZIP/JAR文件如果您傳遞了錯誤類型的斜槓或自動轉換它們,則拋出異常。對於以斜線結尾的目錄,由於無法自動糾正,所以應該記錄它。我提交了一個錯誤報告,但尚未被接受。 – Gili 2009-08-16 15:52:38
經典的Sun/Oracle。關閉爲「不是bug」:http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6873352 – Gili 2012-01-17 18:06:13
下面是一些示例代碼使用的JarOutputStream創建一個JAR文件:
還有一個「怪癖」注意:所有的JarEntry的名字不應該與「/」開頭。
例如:清單文件的jar條目名稱是「META-INF/MANIFEST.MF」,而不是「/META-INF/MANIFEST.MF」。
所有jar條目都應遵循相同的規則。
您可以使用此代碼做到這一點:
public void write(File[] files, String comment) throws IOException {
FileOutputStream fos = new FileOutputStream(PATH + FILE);
JarOutputStream jos = new JarOutputStream(fos, manifest);
BufferedOutputStream bos = new BufferedOutputStream(jos);
jos.setComment(comment);
for (File f : files) {
print("Writing file: " + f.toString());
BufferedReader br = new BufferedReader(new FileReader(f));
jos.putNextEntry(new JarEntry(f.getName()));
int c;
while ((c = br.read()) != -1) {
bos.write(c);
}
br.close();
bos.flush();
}
bos.close();
// JarOutputStream jor = new JarOutputStream(new FileOutputStream(PATH + FILE), manifest);
}
PATH
變量:路徑JAR文件
FILE
變量:名稱和格式
也許你應該表現出你目前(非工作)解決方案 – ChssPly76 2009-08-15 06:14:35