Перечисление файлов в каталоге текущего файла JAR - PullRequest
14 голосов
/ 07 декабря 2008

Я делаю игру в JAVA, в которой я хочу создать список файлов в определенном каталоге в моем банке, чтобы я мог убедиться, что у меня есть список тех классов, которые будут использоваться в игре.

Например, скажите, в моей банке у меня есть каталог

mtd/entity/creep/

Я хочу получить список всех файлов .class в этом каталоге , используя код Java из другого класса в jar .

Какой лучший код для этого?

Ответы [ 4 ]

8 голосов
/ 07 декабря 2008

Старый код 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 голос
/ 07 декабря 2008

Вероятно, лучший подход - перечислить классы во время компиляции.

Существует хрупкий подход во время выполнения. Возьмите вас Class (MyClass.class из this.getClass()). Звоните getProtectionDomain. Звоните getCodeSource. Звоните getLocation. Звоните openConnection. (Либо откройте ресурс.) Приведите к JarURLConnection. Звоните getJarFile. Звоните entries. Итерация по проверке getName. Я действительно не рекомендую такой подход.

0 голосов
/ 07 декабря 2008

Помните, что JAR файлы - это просто ZIP файлы, переименованные, и очень просто читать содержимое ZIP файлов в Java:

    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();
   }
0 голосов
/ 07 декабря 2008

Это невозможно, поскольку Java не предоставляет прямой доступ к файлу jar, из которого загружаются классы. Вы можете попытаться проанализировать системное свойство java.class.path, чтобы найти его, но это не сработает при любых обстоятельствах. Или вы можете ограничить, где должен находиться jar-файл, или предоставить список классов другим способом (например, через файл манифеста).

...