tipos - modificar archivos txt en java
¿La mejor manera de listar archivos en Java, ordenados por fecha de modificación? (16)
Quiero obtener una lista de archivos en un directorio, pero quiero ordenarlos de modo que los archivos más antiguos sean los primeros. Mi solución fue llamar a File.listFiles y simplemente recurrir a la lista basada en File.lastModified, pero me preguntaba si había una mejor manera.
Edición: mi solución actual, como se sugiere, es usar un Comparador anónimo:
File[] files = directory.listFiles();
Arrays.sort(files, new Comparator<File>(){
public int compare(File f1, File f2)
{
return Long.valueOf(f1.lastModified()).compareTo(f2.lastModified());
} });
Solución elegante desde Java 8:
File[] files = directory.listFiles();
Arrays.sort(files, Comparator.comparingLong(File::lastModified));
O, si lo desea en orden descendente, simplemente inviértalo:
File[] files = directory.listFiles();
Arrays.sort(files, Comparator.comparingLong(File::lastModified).reversed());
¿Qué hay de enfoque similar, pero sin boxear a los objetos largos:
File[] files = directory.listFiles();
Arrays.sort(files, new Comparator<File>() {
public int compare(File f1, File f2) {
return Long.compare(f1.lastModified(), f2.lastModified());
}
});
Creo que tu solución es la única manera sensata. La única forma de obtener la lista de archivos es usar File.listFiles() y la documentación indica que esto no garantiza el orden de los archivos devueltos. Por lo tanto, debe escribir un Comparator que use File.lastModified() y pasar esto, junto con la matriz de archivos, a Arrays.sort() .
En Java 8:
Arrays.sort(files, (a, b) -> Long.compare(a.lastModified(), b.lastModified()));
Esto podría ser más rápido si tienes muchos archivos. Esto utiliza el patrón decorate-sort-undecorate para que la fecha de última modificación de cada archivo se recupere solo una vez en lugar de cada vez que el algoritmo de clasificación compare dos archivos. Esto reduce potencialmente el número de llamadas de E / S de O (n log n) a O (n).
Sin embargo, es más código, por lo que solo debe usarse si está preocupado principalmente por la velocidad y es considerablemente más rápido en la práctica (que no he comprobado).
class Pair implements Comparable {
public long t;
public File f;
public Pair(File file) {
f = file;
t = file.lastModified();
}
public int compareTo(Object o) {
long u = ((Pair) o).t;
return t < u ? -1 : t == u ? 0 : 1;
}
};
// Obtain the array of (file, timestamp) pairs.
File[] files = directory.listFiles();
Pair[] pairs = new Pair[files.length];
for (int i = 0; i < files.length; i++)
pairs[i] = new Pair(files[i]);
// Sort them by timestamp.
Arrays.sort(pairs);
// Take the sorted pairs and extract only the file part, discarding the timestamp.
for (int i = 0; i < files.length; i++)
files[i] = pairs[i].f;
Existe una manera muy fácil y conveniente de manejar el problema sin ningún comparador adicional. Simplemente codifique la fecha de modificación en la Cadena con el nombre del archivo, ordénelo y luego elimínelo nuevamente.
Use una cadena de longitud fija 20, ponga la fecha modificada (larga) en ella y rellene con ceros a la izquierda. Luego simplemente agregue el nombre del archivo a esta cadena:
String modified_20_digits = ("00000000000000000000".concat(Long.toString(temp.lastModified()))).substring(Long.toString(temp.lastModified()).length());
result_filenames.add(modified_20_digits+temp.getAbsoluteFile().toString());
Lo que pasa es esto aquí:
Nombre del archivo 1: C: / data / file1.html Última modificación: 1532914451455 Última modificación 20 dígitos: 00000001532914451455
Nombre del archivo 1: C: / data / file2.html Última modificación: 1532918086822 Última modificación 20 dígitos: 00000001532918086822
transforma los nombres de archivos a:
Nombre de archivo1: 00000001532914451455C: / data / file1.html
Nombre de archivo2: 00000001532918086822C: / data / file2.html
A continuación, puede simplemente ordenar esta lista.
Todo lo que necesita hacer es eliminar los 20 caracteres más tarde (en Java 8, puede eliminarlo para toda la matriz con una sola línea utilizando la función .replaceAll)
Importaciones:
org.apache.commons.io.comparator.LastModifiedFileComparator
Código:
public static void main(String[] args) throws IOException {
File directory = new File(".");
// get just files, not directories
File[] files = directory.listFiles((FileFilter) FileFileFilter.FILE);
System.out.println("Default order");
displayFiles(files);
Arrays.sort(files, LastModifiedFileComparator.LASTMODIFIED_COMPARATOR);
System.out.println("/nLast Modified Ascending Order (LASTMODIFIED_COMPARATOR)");
displayFiles(files);
Arrays.sort(files, LastModifiedFileComparator.LASTMODIFIED_REVERSE);
System.out.println("/nLast Modified Descending Order (LASTMODIFIED_REVERSE)");
displayFiles(files);
}
Llegué a este post cuando estaba buscando el mismo problema pero en android
. No digo que esta sea la mejor manera de ordenar los archivos por fecha de última modificación, pero es la forma más fácil que he encontrado hasta ahora.
El código de abajo puede ser útil para alguien
File downloadDir = new File("mypath");
File[] list = downloadDir.listFiles();
for (int i = list.length-1; i >=0 ; i--) {
//use list.getName to get the name of the file
}
Gracias
Puede usar la biblioteca Apache LastModifiedFileComparator
import org.apache.commons.io.comparator.LastModifiedFileComparator;
File[] files = directory.listFiles();
Arrays.sort(files, LastModifiedFileComparator.LASTMODIFIED_COMPARATOR);
for (File file : files) {
Date lastMod = new Date(file.lastModified());
System.out.println("File: " + file.getName() + ", Date: " + lastMod + "");
}
Puedes probar el Ordering guayaba:
Function<File, Long> getLastModified = new Function<File, Long>() {
public Long apply(File file) {
return file.lastModified();
}
};
List<File> orderedFiles = Ordering.natural().onResultOf(getLastModified).
sortedCopy(files);
Si los archivos que está clasificando se modifican / actualizan mientras se realiza la clasificación, estará violando el requisito de transitividad del contrato general del comparador. Para evitar este posible error, querrá crear una tabla de búsqueda estática de los últimos valores modificados para usar en el comparador para cada archivo, algo como lo siguiente:
Collection<File> files = ...
final Map<File, Long> staticLastModifiedTimes = new HashMap<File,Long>();
for(final File f : files) {
staticLastModifiedTimes.put(f, f.lastModified());
}
Collections.sort(files, new Comparator<File>() {
@Override
public int compare(final File f1, final File f2) {
return staticLastModifiedTimes.get(f1).compareTo(staticLastModifiedTimes.get(f2));
}
});
También hay una forma completamente diferente que puede ser incluso más fácil, ya que no tratamos con grandes números.
En lugar de ordenar toda la matriz después de recuperar todos los nombres de archivo y las fechas de LastModified, puede insertar cada nombre de archivo solo después de recuperarlo en la posición correcta de la lista.
Puedes hacerlo así:
list.add(1, object1)
list.add(2, object3)
list.add(2, object2)
Después de agregar object2 a la posición 2, moverá object3 a la posición 3.
También puede consultar Apache commons IO , tiene incorporado un comparador de última modificación y muchas otras utilidades agradables para trabajar con archivos.
Collections.sort(listFiles, new Comparator<File>() {
public int compare(File f1, File f2) {
return Long.compare(f1.lastModified(), f2.lastModified());
}
});
donde listFiles
es la colección de todos los archivos en ArrayList
private static List<File> sortByLastModified(String dirPath) {
List<File> files = listFilesRec(dirPath);
Collections.sort(files, new Comparator<File>() {
public int compare(File o1, File o2) {
return Long.compare(o1.lastModified(), o2.lastModified());
}
});
return files;
}
public String[] getDirectoryList(String path) {
String[] dirListing = null;
File dir = new File(path);
dirListing = dir.list();
Arrays.sort(dirListing, 0, dirListing.length);
return dirListing;
}