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

时间:2008-12-06 21:32:41

标签: java class jar loading

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

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

mtd/entity/creep/

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

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

5 个答案:

答案 0 :(得分:8)

旧的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();
        }
    }
}

答案 1 :(得分:1)

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

有一种脆弱的运行时方法。带你ClassMyClass.class的{​​{1}})。致电this.getClass()。致电getProtectionDomain。致电getCodeSource。致电getLocation。 (或者打开资源。)转换为openConnection。致电JarURLConnection。致电getJarFile。通过检查entries来迭代。我真的不推荐这种方法。

答案 2 :(得分:0)

请记住 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();
   }

答案 3 :(得分:0)

问题提出10年后,我提出了另一种解决方法:

   protected function configureDatagridFilters(DatagridMapper $datagridMapper)
    {
        $datagridMapper
            ->add('structure', null, ['label' => 'Structure'], EntityType::class, [
                'class' => 'App\Entity\Structure',
                'query_builder' => function (EntityRepository $er) {
                    return $er->createQueryBuilder('s')
                        ->orderBy('UPPER(s.name)');
                },
            ])

...

答案 4 :(得分:-2)

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