Estoy tratando de investigar un DirecoryStream.Filter ejemplo para newDirectoryStream donde puedo conseguir la lista de todos los archivos de un directorio(y todos sus subdirectorios) que son más de 60 días, como un ejemplo.

DirectoryStream<Path> dirS = Files.newDirectoryStream(Paths.get("C:/myRootDirectory"), <DirectoryStream.filter>);

for (Path entry: dirS) {
    System.out.println(entry.toString());
}

En el código anterior, lo que debería ser el DirectoryStream.filter?
Será una gran ayuda ya que estoy en un proyecto en el que estoy tratando de borrar archivos de más de una cierta marca de hora y pre-java 1.7 File.listFiles() sólo se bloquea.

Podría Files.walkFileTree() proporcionar una opción?

InformationsquelleAutor Ashley | 2014-02-12

2 Comentarios

  1. 8

    Si puedo obtener este derecho, se tienen 2 situaciones:

    1. Crear una personalizada filter para seleccionar los archivos de más de 60 días
    2. Recorrer a través de los subdirectorios (el de toda la FileTree) y recoger su información

    El filtro personalizado es más fácil de implementar con las condiciones de los 60 días de implementado el uso de Calendar clase:

    DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
        @Override
        public boolean accept(Path entry) throws IOException {BasicFileAttributes attr = Files.readAttributes(entry,BasicFileAttributes.class);
        FileTime creationTime = attr.creationTime();
        Calendar cal = Calendar.getInstance();
        int days = cal.fieldDifference(new Date(creationTime.toMillis()),Calendar.DAY_OF_YEAR);
            return (Math.abs(days) > 60);
            }
      };

    La ejecución normal sería sólo buscar los archivos en el directorio raíz. Para buscar subdirectorio, su conjetura de uso de walkFileTree() es correcto.

    Sin embargo, esto requiere de una implementación de la FileVisitor interfaz, una simple aplicación de la que por suerte viene con 7 – SimpleFileVisitor.

    A recorrer a través de los subdirectorios, usted puede elegir reemplazar un directorio específico del método que he utilizado preVisitDirectory de SimpleFileVisitor aquí:

    Files.walkFileTree(dirs, new SimpleFileVisitor<Path>() {
                @Override
                public FileVisitResult preVisitDirectory(Path file,
                        BasicFileAttributes attrs) {

    Desde preVisitDirectory será hecha a la medida de return FileVisitResult.CONTINUE; en caso de que usted no tiene ninguna restricción adicional, nos gustaría aprovechar preVisitDirectory método para iterar a través de nuestro directorio de 1 a la vez mientras se aplica el filtro.

    Files.walkFileTree(dirs, new SimpleFileVisitor<Path>() {
                @Override
                public FileVisitResult preVisitDirectory(Path file,
                        BasicFileAttributes attrs) {
    
                    DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
                        @Override
                        public boolean accept(Path entry) throws IOException {
                            BasicFileAttributes attr = Files.readAttributes(entry,
                                    BasicFileAttributes.class);
                            FileTime creationTime = attr.creationTime();
                            Calendar cal = Calendar.getInstance();
                            int days = cal.fieldDifference(
                                    new Date(creationTime.toMillis()),
                                    Calendar.DAY_OF_YEAR);
                            return (Math.abs(days) > 60);
                        }
                    };
                    try (DirectoryStream<Path> stream = Files.newDirectoryStream(
                            file, filter)) {
                        for (Path path : stream) {
                            System.out.println(path.toString());
                        }
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
                    return FileVisitResult.CONTINUE;
    
                }
            }); 

    Esto daría a los archivos de todo el directorio y subdirectorio estructuras para los criterios de filtro, completar principal método a continuación:

    public static void main(String[] args) throws IOException {
            Path dirs = Paths.get("C:/");
    
            Files.walkFileTree(dirs, new SimpleFileVisitor<Path>() {
                @Override
                public FileVisitResult preVisitDirectory(Path file,
                        BasicFileAttributes attrs) {
    
                    DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
                        @Override
                        public boolean accept(Path entry) throws IOException {
                            BasicFileAttributes attr = Files.readAttributes(entry,
                                    BasicFileAttributes.class);
                            FileTime creationTime = attr.creationTime();
                            Calendar cal = Calendar.getInstance();
                            int days = cal.fieldDifference(
                                    new Date(creationTime.toMillis()),
                                    Calendar.DAY_OF_YEAR);
                            return (Math.abs(days) > 60);
                        }
                    };
                    try (DirectoryStream<Path> stream = Files.newDirectoryStream(
                            file, filter)) {
                        for (Path path : stream) {
                            System.out.println(path.toString());
                        }
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
                    return FileVisitResult.CONTINUE;
    
                }
            });
    
        }
    • Gracias por estos detalles.
    • seguro que eres bienvenida
  2. 3

    Simplemente crear un nuevo DirectoryStream.Filter instancia que devuelve true si la Path objeto es mayor de 60 días.

    DirectoryStream<Path> dirStream = Files.newDirectoryStream(Paths.get("/some/path"), new Filter<Path>() {
        @Override
        public boolean accept(Path entry) throws IOException {
            FileTime fileTime = Files.getLastModifiedTime(entry);
            long millis = fileTime.to(TimeUnit.MILLISECONDS);
            Calendar today = Calendar.getInstance();
            //L is necessary for the result to correctly be calculated as a long 
            return today.getTimeInMillis() > millis + (60L * 24 * 60 * 60 * 1000);
        }
    });

    Tenga en cuenta que esto sólo le dará los archivos en la raíz del directorio especificado Path, es decir. el Path argumento pasado a newDirectoryStream(..).

    Si quieres todos los archivos en subdirectorios así, Files.walkFileTree(..) es probablemente más fácil de usar. Usted sólo tendrá que implementar un FileVisitor que almacena un List o Set de Path objetos que recoger a lo largo de la manera, utilizando la misma lógica que el Filter arriba.

Dejar respuesta

Please enter your comment!
Please enter your name here