将文件列在当前JAR文件的目录中

时间:2022-08-09 00:09:42

I am making a game in JAVA where I want to come up with a list of files in a certain directory in my jar so I can make sure to have a list of those classes to be used in the game.

我正在JAVA制作一个游戏,我想在我的jar中的某个目录中找到一个文件列表,这样我就可以确保在游戏中使用这些类的列表。

For example say in my jar I have a directory

例如,在我的jar中我有一个目录

mtd/entity/creep/

I want to get a list of all the .class files in that directory using java code from another class in the jar.

我想使用jar中另一个类的java代码获取该目录中所有.class文件的列表。

What is the best code to do so?

这样做的最佳代码是什么?

4 个解决方案

#1


8  

Old java1.4 code, but that would give you the idea:

旧的java1.4代码,但这会给你的想法:

private static List getClassesFromJARFile(String jar, String packageName) throws Error
{
    final List classes = new ArrayList();
    JarInputStream jarFile = null;
    try
    {
        jarFile = new JarInputStream(new FileInputStream(jar));
        JarEntry jarEntry;
        do 
        {       
            try
            {
                jarEntry = jarFile.getNextJarEntry();
            }
            catch(IOException ioe)
            {
                throw new CCException.Error("Unable to get next jar entry from jar file '"+jar+"'", ioe);
            }
            if (jarEntry != null) 
            {
                extractClassFromJar(jar, packageName, classes, jarEntry);
            }
        } while (jarEntry != null);
        closeJarFile(jarFile);
    }
    catch(IOException ioe)
    {
        throw new CCException.Error("Unable to get Jar input stream from '"+jar+"'", ioe);
    }
    finally
    {
        closeJarFile(jarFile);
    }
   return classes;
}
private static void extractClassFromJar(final String jar, final String packageName, final List classes, JarEntry jarEntry) throws Error
{
    String className = jarEntry.getName();
    if (className.endsWith(".class")) 
    {
        className = className.substring(0, className.length() - ".class".length());
        if (className.startsWith(packageName))
        {
            try
            {
                classes.add(Class.forName(className.replace('/', '.')));
            } catch (ClassNotFoundException cnfe)
            {
                throw new CCException.Error("unable to find class named " + className.replace('/', '.') + "' within jar '" + jar + "'", cnfe);
            }
        }
    }
}
private static void closeJarFile(final JarInputStream jarFile)
{
    if(jarFile != null) 
    { 
        try
        {
            jarFile.close(); 
        }
        catch(IOException ioe)
        {
            mockAction();
        }
    }
}

#2


1  

Probably the best approach is to list the classes at compile time.

可能最好的方法是在编译时列出类。

There is a fragile runtime approach. Take you Class (MyClass.class of this.getClass()). Call getProtectionDomain. Call getCodeSource. Call getLocation. Call openConnection. (Alternatively open a resource.) Cast to JarURLConnection. Call getJarFile. Call entries. Iterate through checking getName. I really do not recommend this approach.

有一种脆弱的运行时方法。拿你的Class(this.getClass()的MyClass.class)。调用getProtectionDomain。调用getCodeSource。调用getLocation。调用openConnection。 (或者打开资源。)转换为JarURLConnection。调用getJarFile。来电条目。通过检查getName来迭代。我真的不推荐这种方法。

#3


0  

Remember that JAR files are just ZIP files renamed, and it's very easy to read the contents of ZIP files in Java:

请记住,JAR文件只是重命名的ZIP文件,并且很容易在Java中读取ZIP文件的内容:

    File jarName = null;
    try
    {
        jarName = new File (Dir.class.getProtectionDomain().getCodeSource().getLocation().toURI());
    }
    catch (Exception e)
    {
        e.printStackTrace();    
    }

    try 
    {
      ZipFile zf=new ZipFile(jarName.getAbsoluteFile());
      Enumeration e=zf.entries();
      while (e.hasMoreElements()) 
      {
          ZipEntry ze=(ZipEntry)e.nextElement();
          System.out.println(ze.getName());
      }
      zf.close();
   } catch (IOException e) 
   {
      e.printStackTrace();
   }

#4


-2  

It's not possible, as Java doesn't provide direct access to the jar file the classes are loaded from. You could try to parse the java.class.path system property to find it, but that wouldn't work under all circumstances. Or you could restrict on where the jar file has to reside, or provide the list of the classes in a different way (for example via the manifest file).

这是不可能的,因为Java不提供对从中加载类的jar文件的直接访问。您可以尝试解析java.class.path系统属性以查找它,但这在所有情况下都不起作用。或者您可以限制jar文件驻留的位置,或以不同的方式提供类的列表(例如通过清单文件)。

#1


8  

Old java1.4 code, but that would give you the idea:

旧的java1.4代码,但这会给你的想法:

private static List getClassesFromJARFile(String jar, String packageName) throws Error
{
    final List classes = new ArrayList();
    JarInputStream jarFile = null;
    try
    {
        jarFile = new JarInputStream(new FileInputStream(jar));
        JarEntry jarEntry;
        do 
        {       
            try
            {
                jarEntry = jarFile.getNextJarEntry();
            }
            catch(IOException ioe)
            {
                throw new CCException.Error("Unable to get next jar entry from jar file '"+jar+"'", ioe);
            }
            if (jarEntry != null) 
            {
                extractClassFromJar(jar, packageName, classes, jarEntry);
            }
        } while (jarEntry != null);
        closeJarFile(jarFile);
    }
    catch(IOException ioe)
    {
        throw new CCException.Error("Unable to get Jar input stream from '"+jar+"'", ioe);
    }
    finally
    {
        closeJarFile(jarFile);
    }
   return classes;
}
private static void extractClassFromJar(final String jar, final String packageName, final List classes, JarEntry jarEntry) throws Error
{
    String className = jarEntry.getName();
    if (className.endsWith(".class")) 
    {
        className = className.substring(0, className.length() - ".class".length());
        if (className.startsWith(packageName))
        {
            try
            {
                classes.add(Class.forName(className.replace('/', '.')));
            } catch (ClassNotFoundException cnfe)
            {
                throw new CCException.Error("unable to find class named " + className.replace('/', '.') + "' within jar '" + jar + "'", cnfe);
            }
        }
    }
}
private static void closeJarFile(final JarInputStream jarFile)
{
    if(jarFile != null) 
    { 
        try
        {
            jarFile.close(); 
        }
        catch(IOException ioe)
        {
            mockAction();
        }
    }
}

#2


1  

Probably the best approach is to list the classes at compile time.

可能最好的方法是在编译时列出类。

There is a fragile runtime approach. Take you Class (MyClass.class of this.getClass()). Call getProtectionDomain. Call getCodeSource. Call getLocation. Call openConnection. (Alternatively open a resource.) Cast to JarURLConnection. Call getJarFile. Call entries. Iterate through checking getName. I really do not recommend this approach.

有一种脆弱的运行时方法。拿你的Class(this.getClass()的MyClass.class)。调用getProtectionDomain。调用getCodeSource。调用getLocation。调用openConnection。 (或者打开资源。)转换为JarURLConnection。调用getJarFile。来电条目。通过检查getName来迭代。我真的不推荐这种方法。

#3


0  

Remember that JAR files are just ZIP files renamed, and it's very easy to read the contents of ZIP files in Java:

请记住,JAR文件只是重命名的ZIP文件,并且很容易在Java中读取ZIP文件的内容:

    File jarName = null;
    try
    {
        jarName = new File (Dir.class.getProtectionDomain().getCodeSource().getLocation().toURI());
    }
    catch (Exception e)
    {
        e.printStackTrace();    
    }

    try 
    {
      ZipFile zf=new ZipFile(jarName.getAbsoluteFile());
      Enumeration e=zf.entries();
      while (e.hasMoreElements()) 
      {
          ZipEntry ze=(ZipEntry)e.nextElement();
          System.out.println(ze.getName());
      }
      zf.close();
   } catch (IOException e) 
   {
      e.printStackTrace();
   }

#4


-2  

It's not possible, as Java doesn't provide direct access to the jar file the classes are loaded from. You could try to parse the java.class.path system property to find it, but that wouldn't work under all circumstances. Or you could restrict on where the jar file has to reside, or provide the list of the classes in a different way (for example via the manifest file).

这是不可能的,因为Java不提供对从中加载类的jar文件的直接访问。您可以尝试解析java.class.path系统属性以查找它,但这在所有情况下都不起作用。或者您可以限制jar文件驻留的位置,或以不同的方式提供类的列表(例如通过清单文件)。