我有一个程序的实现,该程序可以对大文件中的行进行排序,该文件由于大小而无法完全加载到内存中。 我的算法将该文件拆分为几个文件,这些文件在内部进行排序,然后,它接受两个排序的文件,将其逐行合并为第三个文件。重复最后一步,直到只剩下一个文件。 算法可以按预期工作,但是我想脱离文件并使用自定义数据源:例如,对数据库中的行进行排序,而不对文件中的行进行排序,或者使用简单的集合作为测试的数据源
重要的是,可以打开我的算法文件以进行读取或写入。我的想法是使用方法DataSource
和String readLine()
实现void writeLine(String line)
接口。
对于数据库和集合,此接口可以轻松实现,因为它们支持交替的读写。但是对于文件,实施变得更加困难,因为可以在读取模式或写入模式下打开文件。
因此,如果某些其他代码将与我的界面一起使用,它们将有可能交替调用读写操作,这将破坏FileDataSource的实现,因为readLine()
将始终在调用writeLine之后返回第一行。
这是问题。是否有可能用Files实现这种接口?或者,也许我应该考虑其他接口和其他方法?我被困住了,不知道该怎么办。
让我用代码解释我的意思:
对于CollectionDataSource来说,一切都是微不足道的(我省略了超出范围验证的索引)
public class CollectionDataSource implements DataSource {
private List<String> list = new ArrayList<>();
private int currentReadPosition = 0;
public String readLine() {
return list.get(currentReadPosition++);
}
public void writeLine(String line) {
list.add(line);
}
}
但是使用FileDataSource不能结束于此:
public class FileDataSource implements DataSource {
private File file = new File("path/to/file.txt");
private Scanner reader = new Scanner(file);
private PrintWriter writer = new PrintWriter(new FileWriter(file));
public String readLine() {
return reader.nextLine();
}
public void writeLine(String line) {
writer.println(line);
}
}
您需要添加以下内容:
public class FileDataSource {
private File file = new File("path/to/file.txt");
private Scanner reader;
private PrintWriter writer;
private Mode mode = Mode.NONE;
public String readLine() throws IOException {
changeMode(Mode.READ);
return reader.nextLine();
}
public void writeLine(String line) throws IOException {
changeMode(Mode.WRITE);
writer.println(line);
}
private void changeMode(Mode newMode) throws IOException {
if (newMode == mode) return;
switch (newMode) {
case NONE:
reader = null;
writer = null;
break;
case READ:
if (writer != null) {
writer.close();
}
reader = new Scanner(file);
break;
case WRITE:
if (reader != null) {
reader.close();
}
writer = new PrintWriter(new FileWriter(file, true));
break;
}
mode = newMode;
}
enum Mode {
NONE,
READ,
WRITE
}
}
即使考虑到我对此代码有很多注释的事实,它也无法按预期工作。但这是我能做的最好的事情。
代码的输出结果:
DataSource source = new …..
source.writeLine("1");
source.writeLine("2");
source.writeLine("3");
System.out.println(source.readLine());
System.out.println(source.readLine());
source.writeLine("4");
System.out.println(source.readLine());
使用CollectionDataSource是:
1
2
3
期望和正确的东西
但是对于FileDataSource来说
1
2
1
我了解原因,但不了解如何解决。 抱歉,我的帖子太详细了,但是我怕被误解了