Question

Je suis en train de créer un jeu dans JAVA pour lequel je veux créer une liste de fichiers dans un certain répertoire de mon pot afin de pouvoir être sûr d'avoir une liste de ces classes à utiliser dans le jeu.

Par exemple, dites dans mon pot que j'ai un répertoire

mtd/entity/creep/

Je souhaite obtenir la liste de tous les fichiers .class de ce répertoire à l'aide du code java d'une autre classe du fichier jar .

Quel est le meilleur code pour le faire?

Était-ce utile?

La solution

Ancien code java1.4, mais cela vous donnerait une idée:

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

Autres conseils

La meilleure approche consiste probablement à répertorier les classes au moment de la compilation.

Il existe une approche d'exécution fragile. Prenez vous Classe ( MyClass.class de this.getClass () ). Appelez getProtectionDomain . Appelez getCodeSource . Appelez getLocation . Appelez openConnection . (Vous pouvez également ouvrir une ressource.) Transformez en JarURLConnection . Appelez getJarFile . Appelez entrées . Itérez en vérifiant getName . Je ne recommande vraiment pas cette approche.

N'oubliez pas que les fichiers JAR ne sont que des fichiers ZIP renommés. Il est très facile de lire le contenu des fichiers ZIP en 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 ans après la question, je propose une autre façon de faire le travail:

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);
        }
    }

Ce n'est pas possible, car Java ne fournit pas d'accès direct au fichier jar à partir duquel les classes sont chargées. Vous pouvez essayer d'analyser la propriété système java.class.path pour la trouver, mais cela ne fonctionnera pas dans toutes les circonstances. Vous pouvez également limiter l'emplacement du fichier jar ou fournir une liste différente des classes (par exemple, via le fichier manifeste).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top