用Java解析一个没有很好的大文件

我必须解决一个接近解析一个巨大的文件,如3 GB或更高的问题。 好吧,该文件的结构如下,伪xml文件如下:

   
... others doc...

浏览网络我已经阅读了一些遇到管理文件问题的人,但他们建议我用NIO映射文件。 所以我认为解决方案过于庞大,可能会让我抛出exception。 所以我认为我的问题是解决2个doutbs:

  1. 如何及时有效地阅读3 GB文本文件
  2. 如何有效地解析docFileNoxx中的html摘要,并将规则应用于html的标记以提取标记的post。

那么..我试着用这种方式解决第一个问题:

  1. _reader = new BufferedReader(new FileReader(filePath))//创建文件的缓冲区读取器
  2. _currentLine = _reader.readLine(); //我迭代逐行读取它的文件
  3. 对于每一行,我将行附加到String变量,直到遇到标记
  4. 因此,使用JSOUP和后期CSSfilter,我提取内容,并将其存档。

那么提取25 MB的过程平均需要大约88秒….所以我想执行它。

我可以进行提取吗?

无论你做什么,都不要做(伪代码):

 String data = ""; for line in file { data += line; } 

但是使用StringBuilder:

 StringBuilder data = new StringBuilder(); for line in file { data.append(line); } return data.toString(); 

此外,考虑遍历文件并创建仅包含有趣部分的地图。 我假设您没有XML但只看起来有点像它,您给出的示例是内容的公平表示。

 Map entries = new HashMap(1000); StringBuilder entryData = null; for line in file { if line starts with "" { // Content of this entry starts here entryData = new StringBuilder(); } else if line starts with "" { // content of this entry ends here // so store content, and indicate that the entry is finished by // setting data to null entries.put(docFileNo, entryData.toString); entryData = null; } else if entryData is not null { // we're in an entry as data is not null, so store the line entryData.append(line); } } 

地图仅包含条目大小的字符串,这使得它们更容易处理。 我认为您需要根据真实数据进行调整,但这是您可以在大约半小时内测试的内容。

线索是entryData。 它不仅是构建1个条目的数据的StringBuilder,而且如果不是null,它还表示我们看到了一个开始条目标记(div),如果为null,我们看到结束标记()表示不需要存储下一行。

我假设您要保留doc号,并且XXXposttag是常量。

可以使用Scanner类来实现此逻辑的替代实现。

对于大型XML文件,最好使用SAX样式解析器,这些解析器不会尝试在内存中为整个XML文件构建文档对象模型。 我不会尝试逐行读取XML文件,我会在SAX实现中调用适当的方法。 Oracle有一个教程

如果您的问题是光盘部件,则可以通过使用具有大缓冲区的BufferedInputStream来加速该过程 – 例如,在以下示例中为256KB:

 InputStream in = new BufferedInputStream(new FileInputStream(filePath),256*1024))); new BufferedReader(new InputStreamReader(in)); 

如果问题是CPU并且您有一台多核机器,您可以尝试将工作转移到单独的线程中。