Перечисление файлов в каталоге текущего файла JAR

StackOverflow https://stackoverflow.com/questions/346811

  •  19-08-2019
  •  | 
  •  

Вопрос

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

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

mtd/entity/creep/

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

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

Это было полезно?

Решение

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

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

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

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

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

Через 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);
        }
    }

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top