sábado, 21 de abril de 2012

Listar archivos en un JAR

Listar archivos en Java es muy sencillo, pero cuando tales archivos se encuentran dentro de un JAR el método listFiles() no funciona. Si buscas un poco seguro encuentras como hacerlo en java2s ó en stackoverflow.

Aquí dejo un método basado en la respuesta de stackoverflow con unas pequeñas modificaciones que lo hacen más flexible:

public List<String> listFiles4JAR(Class clazz, String pack, String ext, boolean includeSubPackage) {

        CodeSource src = clazz.getProtectionDomain().getCodeSource();
        List<String> list = new ArrayList<String>();
        String extension = ext.contains(".") ? ext : "." + ext;
        pack = pack.replace('.', '/');

        int numFolders = 0;
        if( !includeSubPackage ){
            numFolders = pack.split("/").length;
        }
        
        try{

            if(src != null){

                String location = src.getLocation().getPath().replaceAll("%20", " ").replaceAll("!/", "");
                URL jarUrl = new URL(location);

                ZipInputStream zip = new ZipInputStream(jarUrl.openStream());
                ZipEntry ze = null;

                while((ze = zip.getNextEntry()) != null){
                    String entryName = ze.getName();

                    if(entryName.startsWith(pack)
                            && (entryName.endsWith(extension.toLowerCase())
                            || entryName.endsWith(extension.toUpperCase()))){
                        
                        if( !includeSubPackage ){
                            
                            if( numFolders == entryName.split("/").length-1 ){
                                list.add(entryName);
                            }
                            continue;
                        }
                        
                        list.add(entryName);
                    }
                }

            }

        }catch(IOException ex){
            Logger.getAnonymousLogger().log(Level.SEVERE, ext);
        }

        return list;
    }


donde:
            clazz es un clase que se encuentra en el JAR que queremos inspeccionar
            pack es el paquete a examinar
            ext es la extensión de los archivos a listar
            includeSubPackage indica si se listan o no los archivos de los sub-paquetes

Ahora solo queda colocar el método en una clase Utils, digamos JARUtils. De esta forma podremos llamar a nuestro método desde cualquier parte:
public class JARUtils {

    private static final JARUtils jarUtis = new JARUtils();

    private JARUtils() {
    }

    public static JARUtils getInstance() {
        return jarUtis;
    }

    ...

}
Y finalmente hacemos algo como:
List<String> list = JARUtils.getInstance().listFiles4JAR(this.getClass(), "un.paquete.con.imagenes", "png", false);
que nos devolverá la lista de imágenes png en el paquete un.paquete.con.imagenes que se encuentra en el JAR que contiene a la clase que realiza la llamada this.getClass().


0 comentarios:

Publicar un comentario