6

所以我试图通过检查 mainfest 文件中的一些值来查看 .jar 是否有效。使用java读取和解析文件的最佳方法是什么?我想用这个命令来提取文件

jar -xvf anyjar.jar META-INF/MANIFEST.MF

但我可以做类似的事情:

File manifest = Command.exec("jar -xvf anyjar.jar META-INF/MAINFEST.MF");

然后使用一些缓冲的阅读器或其他东西来解析文件的行?

谢谢你的帮助...

4

3 回答 3

12

使用该jar工具的问题在于它需要安装完整的 JDK。许多 Java 用户只会安装 JRE,其中不包括jar.

此外,jar必须在用户的 PATH 上。

因此,我建议使用正确的 API,如下所示:

Manifest m = new JarFile("anyjar.jar").getManifest();

这实际上应该更容易!

于 2013-10-13T15:51:15.220 回答
5

java.lang.Package的 Package 类有方法来做你想做的事。这是使用您的 java 代码获取清单内容的简单方法:

String t = this.getClass().getPackage().getImplementationTitle();
String v = this.getClass().getPackage().getImplementationVersion();

我将它放入共享实用程序类中的静态方法中。该方法接受类句柄对象作为参数。这样,我们系统中的任何类都可以在需要时获取自己的清单信息。显然,可以轻松修改该方法以返回值的数组或哈希图。

调用方法:

    String ver = GeneralUtils.checkImplVersion(this);

名为GeneralUtils.java的文件中的方法:

public static String checkImplVersion(Object classHandle)
{
   String v = classHandle.getClass().getPackage().getImplementationVersion();
   return v;
}

并且要获得除了可以通过 Package 类(例如您自己的 Build-Date)获得的清单字段值之外,您还可以获取主要属性并通过这些属性来处理,询问您想要的特定属性。下面的代码是我发现的一个类似问题的一个小修改,可能在 SO 上。(我想记下它,但我把它弄丢了——对不起。)

把它放在一个 try-catch 块中,将一个 classHandle (“this”或 MyClass.class )传递给该方法。"classHandle" 属于 Class 类型:

  String buildDateToReturn = null;
  try
  {
     String path = classHandle.getProtectionDomain().getCodeSource().getLocation().getPath();
     JarFile jar = new JarFile(path);  // or can give a File handle
     Manifest mf = jar.getManifest();
     final Attributes mattr = mf.getMainAttributes();
     LOGGER.trace(" --- getBuildDate: "
           +"\n\t path:     "+ path
           +"\n\t jar:      "+ jar.getName()
           +"\n\t manifest: "+ mf.getClass().getSimpleName()
           );

     for (Object key : mattr.keySet()) 
     {
        String val = mattr.getValue((Name)key);
        if (key != null && (key.toString()).contains("Build-Date"))
        {
           buildDateToReturn = val;
        }
     }
  }
  catch (IOException e)
  { ... }

  return buildDateToReturn;
于 2014-04-24T21:58:55.370 回答
3

最简单的方法是使用 JarURLConnection 类:

String className = getClass().getSimpleName() + ".class";
String classPath = getClass().getResource(className).toString();
if (!classPath.startsWith("jar")) {
    return DEFAULT_PROPERTY_VALUE;
}

URL url = new URL(classPath);
JarURLConnection jarConnection = (JarURLConnection) url.openConnection();
Manifest manifest = jarConnection.getManifest();
Attributes attributes = manifest.getMainAttributes();
return attributes.getValue(PROPERTY_NAME);

因为在某些情况下...class.getProtectionDomain().getCodeSource().getLocation();给出了带有 的路径vfs:/,所以这应该另外处理。

或者,使用 ProtectionDomain:

File file = new File(getClass().getProtectionDomain().getCodeSource().getLocation().toURI());
if (file.isFile()) {
    JarFile jarFile = new JarFile(file);
    Manifest manifest = jarFile.getManifest();
    Attributes attributes = manifest.getMainAttributes();
    return attributes.getValue(PROPERTY_NAME);
}
于 2016-02-17T11:56:31.013 回答