2017-10-13 37 views
1

所以基本上,对于我正在处理的这个任务,我们必须从一个大约一百万行的大文件读入,将关键字和值存储在我们选择的数据结构(我使用散列表)提供了更改键值的功能,然后将键值存储保存回文件中。我正在使用杜鹃哈希方法以及我从哈佛大学一篇名为“存储”的文章中找到的方法来完成这一任务,我对它的所有方面都很满意。我唯一担心的是只用程序读取文件中的数据的时间。如何加速从一个大文件读取(Java)

文件格式,因此每行有这样写的一个键(整数)和值(字符串):

12345 'ABCDEF'

23456 'bcdefg'

等上。我已经拿出来阅读的方法是这样的:

private static void readData() throws IOException { 
    try { 
     BufferedReader inStream = new BufferedReader(new FileReader("input/data.db")); 
     StreamTokenizer st = new StreamTokenizer(inStream); 
     String line = inStream.readLine(); 
     do{ 
      String[] arr = line.split(" "); 
      line = inStream.readLine(); 
      Long n = Long.parseLong(arr[0]); 
      String s = arr[1]; 
      //HashNode<Long, String> node = HashNode.create(n, s); 
      //table = HashTable.empty(); 
      //table.add(n, s); 

     }while(line != null); 
    } catch (FileNotFoundException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

} 

的方法工作正常,实际上得到的数据,但是我有一百万行我们的测试文件测试,它花了大约20分钟,它通过阅读所有内容来获取所有内容。当然,这不是从文件中读取数据的快速时间,我认为必须有更好的方式来完成这项工作。

我已经尝试了几种不同的输入方法(使用FileInputStream的BufferedInputStream,使用扫描程序,但是文件扩展名是.db所以Scanner没有工作,我最初没有tokenizer,但添加它希望它会有所帮助) 。我不知道我运行它的计算机是否有很大的不同。我有一台MacBook Air,目前我正在运行;然而,我有一个伴侣在他的笔记本电脑上运行它,看看它是否可以帮助它。任何关于如何帮助这个事情的投入,或者我可能会做什么来减慢事情都会非常诚恳和非常感激。

P.S.请不要恨我在Mac上编程:-)

回答

1

可以使用,下面的代码是用Java编写8风格,但如果需要,可以很容易地修改Java的早期版本:

 Map<Long, String> map = new HashMap<>(); 
     Files.lines(Paths.get("full-path-to-your-file")).forEach(line -> { 
      String[] arr = line.split(" "); 
      Long number = Long.parseLong(arr[0]); 
      String string = arr[1]; 
      map.put(number, string); 
     }); 

有一个额外的自Files.lines(..).forEach(...)以来并行执行的性能增益。这意味着线路不会按顺序排列(在我们的情况下 - 您不需要它),以防您需要它以便您可以拨打:forEachOrdered()

在我的MacBook上,花费不到5秒的时间将200万条这样的记录写入文件,然后读取并填充地图。

+1

这对我来说真棒。我调整了程序的其余部分,完成了散列函数,现在需要大约2秒钟才能读取和存储100万行。谢谢! – koko985

1

摆脱StreamTokenizer。您可以使用BufferedReader.readLine()读取每秒数百万行,这就是您真正在做的事情:无需标记。

但我强烈怀疑这段时间没有花在I/O上,而是在处理每一行。

NB你do/while循环通常写成while循环:

while ((line = in.readLine()) != null) 

更清晰的那样,并没有NPE的风险。 “java.nio.file *”

+0

我已经等待代码完全计算,最后没有错误。另外,我有意忽略第一行,第一行是一个包含文件名称的头文件,我不想让它读入。不幸的是,这是整个Main类,而不是简单地调用此方法的main方法,那到目前为止。我将移除标记器以查看是否可以以任何方式提供帮助。 – koko985