【发布时间】:2016-01-08 08:33:02
【问题描述】:
我知道这种异常有很多问题,我确实找到了解决方案,但我的问题是不同项目中的相同代码不会抛出异常而这个异常。两个项目都有相同版本的 Java 和其他库。
基本上我有这个小函数,它从目录中检索文件列表,按时间戳对它们进行排序,然后返回绝对文件名列表:
public static List<String> getFiles(String dir) {
List<String> fileList = new ArrayList<String>();
File[] files = new File(dir).listFiles();
// Sort files by the date of their creation (last modification)
Arrays.sort(files, LastModifiedFileComparator.LASTMODIFIED_COMPARATOR);
for (File f : files) {
fileList.add(f.getAbsolutePath());
}
return fileList;
}
基本上,在其中一个项目中,此代码按预期执行,而在其他项目中则抛出IllegalArgumentException: Comparison method violates its general contract!
我知道TimSort 是自 1.7 以来 Java 中的默认排序,其中一种解决方案是使用强制使用旧版 MergeSort 的属性。我没有走那条路……相反,我按照here的建议“缓存”了文件及其时间戳:
public static List<String> getFiles(String dir) {
List<String> fileList = new ArrayList<String>();
File[] files = new File(dir).listFiles();
FileLastModifiedPair[] pairs = new FileLastModifiedPair[files.length];
for (int i = 0; i < files.length; i++) {
pairs[i] = new FileLastModifiedPair(files[i]);
}
// Sort files by the date of their creation (last modification)
Arrays.sort(pairs);
// Take the sorted pairs and extract only the file part, discarding the timestamp
for (FileLastModifiedPair pair : pairs) {
fileList.add(pair.f.getAbsolutePath());
}
return fileList;
}
现在,存在多线程问题,所以让我解释一下我的代码的作用:我有一个任务调度程序,具有固定延迟,调用方法getFiles(String),然后处理每个文件:
private Thread handleFiles () {
return new Thread() {
public void run() {
List<String> files = getFiles("/home/user/files/");
if (files.isEmpty()) {
return;
}
for (String file : files) {
try {
// handle file...
} catch (Exception e) {
// log error...
} finally {
// delete file...
}
}
}
};
}
当应用启动时,这段代码被调用:
Date startOfTomorrow = DateTime.now()
.withTimeAtStartOfDay()
.plusDays(1)
.toDate();
scheduler.scheduleWithFixedDelay(
handleFiles(),
startOfTomorrow,
DELAY_IN_MILLIS);
基本上这是我的两个项目处理文件的方式。 我的问题是:为什么第一个 getFiles(String) 方法在一个项目中有效,而在另一个项目中无效?如果他们使用不同版本的 Java 或其他库(如 Apache commons-io),我会理解,但他们使用相同的版本。
编辑 #1: FileLastModifierPair.java:
public class FileLastModifiedPair implements Comparable<FileLastModifiedPair> {
public File f;
public long t;
public FileLastModifiedPair(File file) {
f = file;
t = file.lastModified();
}
public int compareTo(FileLastModifiedPair that) {
long result = this.t - that.t;
if (result < 0) {
return -1;
} else if (result > 0) {
return 1;
} else {
return 0;
}
}
}
【问题讨论】:
-
向我们展示
LastModifiedFileComparator类代码。 -
@Codebender 那是Apache's commons-io class
标签: java file sorting comparator