Frage

Ich mache ein Spiel in JAVA, wo ich mit einer Liste von Dateien in einem bestimmten Verzeichnis in meinem Glas kommen will, so kann ich sicherstellen, dass eine Liste dieser Klassen haben, um im Spiel verwendet werden.

Zum Beispiel sagen, in meinem Glas Ich habe ein Verzeichnis

mtd/entity/creep/

Ich mag in diesem Verzeichnis eine Liste aller Class-Dateien erhalten mit Java-Code von einer anderen Klasse im Glas .

Was ist der beste Code, dies zu tun?

War es hilfreich?

Lösung

Old java1.4 Code, aber das würde Ihnen die Idee:

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

Andere Tipps

Wahrscheinlich der beste Ansatz ist es, die Klassen während der Kompilierung zur Liste.

Es ist ein zerbrechlicher Runtime-Ansatz. Nehmen Sie Class (MyClass.class von this.getClass()). Call getProtectionDomain. Call getCodeSource. Call getLocation. Call openConnection. (Alternativ öffnet eine Ressource.) Cast JarURLConnection. Call getJarFile. Call entries. Iterieren getName überprüfen. Ich weiß nicht, diesen Ansatz wirklich empfehlen.

Beachten Sie, dass JAR Dateien sind nur ZIP Dateien umbenannt, und es ist sehr einfach, den Inhalt von ZIP Dateien in Java zu lesen:

    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 Jahre nach der Frage, schlage ich einen anderen Weg, um den Job zu tun:

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

Es ist nicht möglich, da Java keinen direkten Zugriff auf die JAR-Datei werden die Klassen von geladenen bietet. Sie könnten versuchen, die java.class.path Systemeigenschaft zu analysieren, sie zu finden, aber das würde unter allen Umständen nicht funktionieren. Oder Sie könnten auf beschränken, in denen die JAR-Datei befinden hat, oder geben Sie die Liste der Klassen in einer anderen Art und Weise (zum Beispiel über die Manifest-Datei).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top