4

我有一个缓冲阅读器,它逐行读取一个大文件以删除重复的行。

而不是将整个文件加载到内存中,我想通过使用两个缓冲读取器来做到这一点:第一个迭代文件的固定部分,将每个部分一个接一个地加载到内存中。

在每次迭代中,第二个缓冲读取器将从第一个缓冲读取器停止的位置到文件末尾检查加载的部分是否不再存在于文件中。

问题是我不能让新的独立缓冲读取器对象(不是引用)从第一个停止的位置开始。

我需要一种方法来找出第一个缓冲阅读器的文件位置,以便我可以告诉第二个缓冲阅读器从哪里开始。

到目前为止我已经尝试过:

将第一个对象发送到第二个的构造函数。

这实际上有效,但两者都有相同的迭代器,所以第一个与第二个一起移动到文件末尾

BufferedReader cleanfilereader2 = new BufferedReader(cleanfilereader);

bufferedReader.mark()设置缓冲阅读器的位置,但我仍然需要知道第一个阅读器的位置。

笔记:

  • 行数不是恒定的
  • 无法将整个文件加载到内存中
  • 时间和记忆都是问题
4

4 回答 4

1

如果文件很大并且时间问题,这可能不是最佳方式,因为您必须经常阅读每一行(O(n^2) 次)。

如果您有足够的内存,我建议逐行读取文件并将每行的哈希值存储在 ArrayList 中。每行只需要 4 个字节(一个整数)。然后你可以在这个数组列表中搜索重复项(快,因为它在内存中)。这为您提供了所有潜在重复项的列表,您只需在删除它们时检查它们是否是真正的重复项。

于 2013-01-24T17:21:07.103 回答
0

如果需要读取当前位置,可以使用FileChannel作为

文件通道在其文件中具有可以查询和修改的当前位置

您可以使用Channels.newInputStream()InputStream从通道创建一个(如果您不想关闭底层通道,则无需关闭它)。

于 2013-01-24T17:14:07.993 回答
0

试试这个……(如果我没听错的话。)

import java.io.*;
class delete{
public static void main(String args[])throws IOException{
FileInputStream fis1=new FileInputStream("delete.java");
FileInputStream fis2=fis1;
String temp="";
byte buff[]=new byte[100];
while(true){
if (fis1.read(buff)==-1)break;
temp=new String(buff);
System.out.print(temp);
if(fis2.read(buff)==-1)break;
temp=new String(buff);
System.out.print(temp);
}}
}

输出:上面的代码。

这个问题真的很有趣。所以请评论讨论。

于 2013-01-24T17:50:10.320 回答
0

您需要BufferedReader.skip但没有 C 喜欢tell给出当前位置。因此删除 BufferedReader,并使用一个简单的随机访问文件,或 java.nio,一个内存映射文件缓冲区。

于 2013-01-24T17:02:10.060 回答