Reputation: 129
What is the fastest way to get files by lastmodified date? I got a directory with some txt files. User can do a research by date, I list all files in the directory by lastmodified date (in File[]) and i search for the right file with the specific date. I use a collection sort using lastmodified date to sort my files. When I get files from my local drive it's fast but when i want to access to a drive on the netword (private network) it can take about 10 minutes to get a file. I know i can't be quicker than the network but is there a solution that can be really faster than my solution?
exemple for my code :
File[] files = repertoire.listFiles();
Arrays.sort(files, new Comparator<File>() {
@Override
public int compare(File o1, File o2) {
return Long.valueOf(o2.lastModified()).compareTo(o1.lastModified());
}
});
for (File element : files) {
// i get the right file;
}
Thanks for your help
Here is the solution :
Path repertoiry = Paths.get(repertoire.getAbsolutePath());
final DirectoryStream<Path> stream = Files.newDirectoryStream(repertoiry, new DirectoryStream.Filter<Path>() {
@Override
public boolean accept(Path entry) throws IOException {
return Files.getLastModifiedTime(entry, LinkOption.NOFOLLOW_LINKS).toMillis() >= (dateRechercheeA.getTime() - (24 * 60 * 60 * 1000)) && Files.getLastModifiedTime(entry, LinkOption.NOFOLLOW_LINKS).toMillis() <= (dateRechercheeB.getTime() + (24 * 60 * 60 * 1000));
}
});
for (Path path : stream) {
if (!path.toFile().getName().endsWith("TAM") && !path.toFile().getName().endsWith("RAM")) {
listFichiers.add(path.toFile());
}
}
Upvotes: 5
Views: 2627
Reputation: 156
With java 7 NIO package it's possible to filter a directory to list only files wanted.
(Warning DirectoryStreams
do not iterate through subdirectories.)
Path repertoire = Paths.get("[repertoire]");
try ( DirectoryStream<Path> stream = Files.newDirectoryStream(repertoire, new DirectoryStream.Filter<Path>() {
@Override
public boolean accept(Path entry) throws IOException {
return Files.getLastModifiedTime(entry, LinkOption.NOFOLLOW_LINKS).toMillis() = [DATE_SEARCHED (long)]
}
})){
for (Path path : stream) {
// Path filtered...
}
}
Normally this solution provide better performance than create a full list of file, sort the list and after that iterate over the list to find the right date.
With your code :
//use final keyword to permit access in the filter.
final Date dateRechercheeA = new Date();
final Date dateRechercheeB = new Date();
Path repertoire = Paths.get("[repertoire]");
try (DirectoryStream<Path> stream = Files.newDirectoryStream(repertoire, new DirectoryStream.Filter<Path>() {
@Override
public boolean accept(Path entry) throws IOException {
long entryDateDays = Files.getLastModifiedTime(entry, LinkOption.NOFOLLOW_LINKS).to(TimeUnit.DAYS);
return !entry.getFileName().endsWith("TAM") //does not take TAM file
&& !entry.getFileName().endsWith("RAM") //does not take RAM file
&& ((dateRechercheeB == null && Math.abs(entryDateDays - TimeUnit.DAYS.toDays(dateRechercheeA.getTime())) <= 1)
|| (dateRechercheeB != null && entryDateDays >= (TimeUnit.DAYS.toDays(dateRechercheeA.getTime()) - 1) && entryDateDays <= (TimeUnit.DAYS.toDays(dateRechercheeA.getTime()) + 1)));
}
})) {
Iterator<Path> it = stream.iterator();
//Iterate good file...
}
The filter is directly made in the accept methods and not after.
JAVA SE 7 - Files - newDirectoryStream()
Upvotes: 3