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

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

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

mtd/entity/creep/

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

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

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
14
0
11 715
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Ответ принят как подходящий

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

После того, как я немного поигрался с этим, я заставил его работать. Большое спасибо!

James Van Boxtel 07.12.2008 09:27

О, это именно то, что мне нужно прямо сейчас - спасибо !!

user21037 14.01.2009 14:48

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

что не так в этом ответе? Я предполагал, что более серьезной проблемой будет поиск пути к файлу jar - на самом деле извлечение содержимого должно быть довольно тривиальным.

Ilja Preuß 09.12.2008 22:37

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

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

Помните, что файлы БАНКА - это просто файлы 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();
   }

Спустя 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);
        }
    }

Другие вопросы по теме