问题
In order to get all files contained in a specified directory and according to some extensions, I'm using the method listFiles of class FileUtils from Apache Commons IO library, as in the following code sample.
ArrayList<String> wildcards = new ArrayList<>();
wildcards.add("*.cpp");
wildcards.add("*.h");
wildcards.add("*.txt");
File dir = new File("/path/to/dir");
Collection<File> found = FileUtils.listFiles(
dir,
new WildcardFileFilter(wildcards, IOCase.SENSITIVE),
DirectoryFileFilter.DIRECTORY);
List<File> files = new ArrayList<>(found);
The order of items in the resulting Collection<File>
varies in the different operating systems, so I would sort them (ie. the wrapping list files
) in according to the following rules.
- The directories should be listed before the files.
- The sorting routine should group files by directory.
Example:
/path/to/dir/first/subpath/main.cpp
/path/to/dir/first/subpath/utils.cpp
/path/to/dir/first/subpath/utils.h
/path/to/dir/first/main.cpp
/path/to/dir/first/utils.cpp
/path/to/dir/first/utils.h
/path/to/dir/second/main.cpp
/path/to/dir/second/utils.cpp
/path/to/dir/second/utils.h
/path/to/dir/README.txt
回答1:
You can use Java 8's stream
s to solve your problem. Something like this should work:
//untested
Map<Path, List<Path>> dirToFileMap = files.stream()
.map(f -> Paths.get(f.getAbsolutePath()))
.collect(Collectors.groupingBy(Path::getParent));
With that map you can achieve what you need. Iterate over keySet
first, for example.
回答2:
Just a matter of typing; below I do not take canonical paths (Windows is case-insensitive), but the gist is clear.
So a Comparator
for sorting:
public class FileComparator extends Comparator<File> {
@Override
public int compareTo(File lhs, File rhs) {
if (lhs == null && rhs == null) {
return 0;
} else if (lhs == null || rhs == null) {
return lhs == null ? -1 : 1;
}
int cmp = compareTo(lhs.getParentFile(), rhs.getParentFile());
if (cmp == 0) {
if (lhs.isDirectory() != rhs.isDirectory()) {
return lhs.isDirectory() ? -1 : 1;
}
cmp = lhs.getName().compareTo(rhs.getName());
}
return cmp;
}
@Override
public boolean equals(Object comparator) {
return comparator != null && comparator.getClass().equals(getClass());
}
}
As always the equals
just compares comparators, not Files.
来源:https://stackoverflow.com/questions/32312738/how-to-sort-listfile-to-list-directories-first-and-grouping-files-by-directory