Domanda

Sto realizzando un gioco in JAVA in cui desidero creare un elenco di file in una determinata directory nel mio vaso in modo da poter avere un elenco di quelle classi da utilizzare nel gioco.

Ad esempio, nel mio vaso ho una directory

mtd/entity/creep/

Voglio ottenere un elenco di tutti i file .class in quella directory usando il codice java di un'altra classe nel vaso .

Qual è il codice migliore per farlo?

È stato utile?

Soluzione

Vecchio codice java1.4, ma questo ti darebbe l'idea:

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

Altri suggerimenti

Probabilmente l'approccio migliore è elencare le classi al momento della compilazione.

Esiste un approccio di runtime fragile. Porta Class ( MyClass.class di this.getClass () ). Chiama getProtectionDomain . Chiama getCodeSource . Chiama getLocation . Chiama openConnection . (In alternativa, apri una risorsa.) Trasmetti in JarURLConnection . Chiama getJarFile . Chiama voci . Scorrere il controllo getName . Non raccomando davvero questo approccio.

Ricorda che i file JAR sono solo ZIP rinominati, ed è molto facile leggere il contenuto dei file ZIP in 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 anni dopo la domanda, propongo un altro modo di fare il lavoro:

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

Non è possibile, poiché Java non fornisce accesso diretto al file jar da cui vengono caricate le classi. Potresti provare ad analizzare la proprietà di sistema java.class.path per trovarla, ma non funzionerebbe in tutte le circostanze. Oppure potresti limitare la posizione del file jar o fornire l'elenco delle classi in modo diverso (ad esempio tramite il file manifest).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top