删除文件第一行/顶行(如堆栈)的最快Java方法
我正在尝试改进java中的外部排序实现 我为临时文件打开了一堆BufferedReader对象。我反复从每个文件中删除顶行。这就突破了Java堆的限制。 我希望有一种更具伸缩性的方法来实现这一点,而不会因为大量构造函数调用而降低速度 一种解决方案是只在需要时打开文件,然后读取第一行,然后将其删除。但我担心这将大大放缓 那么,使用Java库最有效的方法是什么呢 --编辑-- 对于外部排序,通常的方法是将一个大文件分解为多个块文件。对每个块进行排序。然后像对待缓冲区一样对待排序后的文件,从每个文件中弹出最上面的项目,所有这些项目中最小的是全局最小值。然后继续,直到所有项目都完成。 我的临时文件(缓冲区)基本上是BufferedReader对象。对这些文件执行的操作与堆栈/队列操作相同(peek和pop,无需推送)删除文件第一行/顶行(如堆栈)的最快Java方法,java,file,Java,File,我正在尝试改进java中的外部排序实现 我为临时文件打开了一堆BufferedReader对象。我反复从每个文件中删除顶行。这就突破了Java堆的限制。 我希望有一种更具伸缩性的方法来实现这一点,而不会因为大量构造函数调用而降低速度 一种解决方案是只在需要时打开文件,然后读取第一行,然后将其删除。但我担心这将大大放缓 那么,使用Java库最有效的方法是什么呢 --编辑-- 对于外部排序,通常的方法是将一个大文件分解为多个块文件。对每个块进行排序。然后像对待缓冲区一样对待排序后的文件,从每个文件中
我正在努力使这些偷窥和突袭行动更有效率。这是因为使用许多BufferedReader对象会占用太多空间。如果堆空间是主要问题,请使用[BufferedReader的第二种形式][1]并指定一个小的缓冲区大小 [1] :,int) 我为临时文件打开了一堆BufferedReader对象。我反复从每个文件中删除顶行。这就突破了Java堆的限制 这真是一个令人惊讶的说法。除非同时打开数千个文件,否则这不会给堆带来压力。BufferedReader的默认缓冲区大小为8192字节,应该不需要多少额外空间<代码>8192*1000只有约8个字节,与典型Java应用程序的内存使用量相比,这是微不足道的 考虑其他原因导致堆问题的可能性。例如,如果程序保留对其读取的每一行的引用,则会导致堆问题 (或者你认为什么是“太多空间”是不现实的。) 一种解决方案是只在需要时打开文件,然后读取第一行,然后将其删除。但我担心这将大大放缓 毫无疑问,这将是显着缓慢!根本没有有效的方法从文件中删除第一行。不使用Java或任何其他语言。从文件的开头或中间删除字符需要将文件复制到新文件,同时跳过需要删除的字符。没有比这更快的选择了。我现在不使用我的编译器,但我认为这会起作用。编辑:很好 我敦促你对其进行简要介绍并查看。我敢打赌,与文件I/O和比较操作相比,构造函数调用将一文不值
public class FileStack {
private File file;
private long position = 0;
private String cache = null;
public FileStack(File file) {
this.file = file;
}
public String peek() throws IOException {
if (cache != null) {
return cache;
}
BufferedReader r = new BufferedReader(new FileReader(file));
try {
r.skip(position);
cache = r.readLine();
return cache;
} finally {
r.close();
}
}
public String pop() throws IOException {
String r = peek();
if (r != null) {
// if you have \r\n line endings, you may need +2 instead of +1
// if lines could end either way, you'll need something more complicated
position += r.length() + 1;
cache = null;
}
return r;
}
}
您能否更具体地说明您的实现实际在做什么,以及算法打算如何操作?我还不清楚这是怎么写的。你是内存不足还是在文件描述符/句柄上达到了操作系统特定的限制?返回的错误来自堆空间。我认为导致堆空间爆炸的原因是我在BufferedReaders周围有一个包装器。我正在将它们插入优先级队列。取而代之的是,我将创建一个较小的索引类放入优先级队列中,看看它是否有帮助。@chrisangrant-Java探查器会准确地告诉您是什么耗尽了所有内存。我在使用YourKit Java Profiler方面有很好的经验。