Pergunta

Estou fazendo um jogo em Java, onde quero criar uma lista de arquivos em um determinado diretório no meu frasco, para que eu tenha uma lista dessas classes a serem usadas no jogo.

Por exemplo, digamos no meu frasco, eu tenho um diretório

mtd/entity/creep/

Eu quero obter uma lista de todos os arquivos .class nesse diretório Usando o código Java de outra classe no frasco.

Qual é o melhor código para isso?

Foi útil?

Solução

Código Java1.4 antigo, mas isso lhe daria a ideia:

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

Outras dicas

Provavelmente, a melhor abordagem é listar as classes no momento da compilação.

Há uma abordagem frágil de tempo de execução. Levá-lo Class (MyClass.class do this.getClass()). Ligar getProtectionDomain. Ligar getCodeSource. Ligar getLocation. Ligar openConnection. (Alternativamente, abra um recurso.) JarURLConnection. Ligar getJarFile. Ligar entries. Itera através da verificação getName. Eu realmente não recomendo essa abordagem.

Lembre-se disso Jarra Os arquivos são justos fecho eclair arquivos renomeados, e é muito fácil ler o conteúdo de fecho eclair Arquivos em 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 anos após a pergunta, proponho uma outra maneira de fazer o trabalho:

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

Não é possível, pois o Java não fornece acesso direto ao arquivo JAR do qual as classes são carregadas. Você pode tentar analisar a propriedade do sistema java.class.path para encontrá -la, mas isso não funcionaria em todas as circunstâncias. Ou você pode restringir onde o arquivo JAR deve residir ou fornecer a lista das classes de uma maneira diferente (por exemplo, através do arquivo manifesto).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top