我有一个文件夹,其中包含以时间戳命名的文件。
当我尝试浏览每个文件时,它按字母顺序排序并给我这个顺序:
/home/user/buffereddata/1
/home/user/buffereddata/100
/home/user/buffereddata/1000
/home/user/buffereddata/200
/home/user/buffereddata/2000
/home/user/buffereddata/300
但我希望他们这样排序:
/home/user/buffereddata/1
/home/user/buffereddata/100
/home/user/buffereddata/200
/home/user/buffereddata/300
/home/user/buffereddata/1000
/home/user/buffereddata/2000
这是我的代码:
File file = new File(System.getProperty("user.home") + "/buffereddata");
if(file.exists()) {
File[] fileArray = file.listFiles();
Arrays.sort(fileArray);
for(File f : fileArray) {
System.out.println(f);
}
}
是否有一些(最好是简单的)方法以我想要循环遍历文件的方式遍历文件?
答案 0 :(得分:11)
Arrays.sort(fileArray, new Comparator<File>() {
public int compare(File f1, File f2) {
try {
int i1 = Integer.parseInt(f1.getName());
int i2 = Integer.parseInt(f2.getName());
return i1 - i2;
} catch(NumberFormatException e) {
throw new AssertionError(e);
}
}
});
答案 1 :(得分:3)
你需要一个自定义比较器
Arrays.sort(fileArray, new Comparator<File>() {
public int compare(File f1, File f2) {
int n1 = Integer.parseInt(f1.getName());
int n2 = Integer.parseInt(f1.getName());
return Integer.compare(n1, n2);
}});
答案 2 :(得分:1)
虽然其他答案在特定情况中是正确的(其中给定目录中的所有文件名都只是数字),但这里有一个可以比较混合数字/非数字文件名的解决方案,例如: version-1.10.3.txt
以直观的方式,类似于Windows资源管理器的方式:
这个想法(which I have blogged about here。The idea was inspired by this answer here。)是将文件名拆分为数字/非数字段,然后以数字方式比较两个文件名中的每个单独的段(如果两者都是数字的话) ),或字母数字否则:
public final class FilenameComparator implements Comparator<String> {
private static final Pattern NUMBERS =
Pattern.compile("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)");
@Override public final int compare(String o1, String o2) {
// Optional "NULLS LAST" semantics:
if (o1 == null || o2 == null)
return o1 == null ? o2 == null ? 0 : -1 : 1;
// Splitting both input strings by the above patterns
String[] split1 = NUMBERS.split(o1);
String[] split2 = NUMBERS.split(o2);
for (int i = 0; i < Math.min(split1.length, split2.length); i++) {
char c1 = split1[i].charAt(0);
char c2 = split2[i].charAt(0);
int cmp = 0;
// If both segments start with a digit, sort them numerically using
// BigInteger to stay safe
if (c1 >= '0' && c1 <= '9' && c2 >= 0 && c2 <= '9')
cmp = new BigInteger(split1[i]).compareTo(new BigInteger(split2[i]));
// If we haven't sorted numerically before, or if numeric sorting yielded
// equality (e.g 007 and 7) then sort lexicographically
if (cmp == 0)
cmp = split1[i].compareTo(split2[i]);
// Abort once some prefix has unequal ordering
if (cmp != 0)
return cmp;
}
// If we reach this, then both strings have equally ordered prefixes, but
// maybe one string is longer than the other (i.e. has more segments)
return split1.length - split2.length;
}
}
然后您可以使用比较器:
Arrays.sort(fileArray, Comparators.comparing(File::getName, new FilenameComparator()));
答案 3 :(得分:-1)
基于this answer:
您可以使用比较功能定义自己的比较器:
public class FileSizeComparator implements Comparator<File> {
public int compare( File a, File b ) {
String aName = a.getName();
String bName = b.getName();
// make both strings equal size by padding 0s to the smaller one
// then compare the strings
return aName.compareTo(bName); // dictionary order!
}
}
compareTo
是一种String
类方法,对您有利。
"0100".compareTo("1000"); // < 0
"0100".compareTo("0200"); // < 0
"0200".compareTo("1000"); // < 0
因此,如果您有100,200,1000,那么您将获得100,200,1000而不是100,1000,200!
应该工作,而不是测试!