Список файлов в каталоге текущего файла JAR

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

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

mtd/entity/creep/

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

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

Ответы

Ответ 1

Старый код 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

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

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

Ответ 3

Через 10 лет после вопроса я предлагаю другой способ сделать работу:

private static void listFilesFromDirectoryInsideAJar(String pathToJar,String directory,String extension) {
        try {
            JarFile jarFile = new JarFile(pathToJar);
            Enumeration<JarEntry> e = jarFile.entries();
            while (e.hasMoreElements()) {
                JarEntry candidat = e.nextElement();
                if (candidat.getName().startsWith(directory) && 
                    candidat.getName().endsWith(extension))
                    LOG.info(candidat.getName());
            }
        } catch (IOException e) {
            LOG.error(e.getMessage(),e);
        }
    }

Ответ 4

Помните, что файлы 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();
   }

Ответ 5

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