Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/395.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用Java解析格式不好的大文件_Java_Parsing_File Io - Fatal编程技术网

用Java解析格式不好的大文件

用Java解析格式不好的大文件,java,parsing,file-io,Java,Parsing,File Io,我必须解决一个问题,接近解析一个巨大的文件,如3 GB或更高。那么,该文件的结构类似于伪xml文件: <docFileNo_1> <otherItems></otherItems> <html> <div=XXXpostag> </html> </docFileNo> ... others doc... <docFileNo_N> <otherItems></otherI

我必须解决一个问题,接近解析一个巨大的文件,如3 GB或更高。那么,该文件的结构类似于伪xml文件:

<docFileNo_1>
<otherItems></otherItems>

<html>
<div=XXXpostag>
</html>

</docFileNo>
   ... others doc... 
<docFileNo_N>
<otherItems></otherItems>

<html>
<div=XXXpostag>
</html>

</docFileNo>

... 其他文件。。。
在网上冲浪时,我读到一些人在管理文件时遇到问题,但他们建议我用NIO映射文件。 所以我认为这个解决方案过于广泛,可能会给我带来一个异常。所以我认为我的问题是解决两个难题:

  • 如何及时有效地阅读 3gb文本文件
  • 如何使用语法分析器 高效地从 docFileNoxx,并将规则应用于 要提取文章的html标记 标签
  • 所以。。我试图通过这种方式解决第一个问题:

  • _读卡器=新的BufferedReader(新的 FileReader(filePath))//创建一个 文件的缓冲区读取器
  • _currentLine=_reader.readLine(); //我迭代文件读取它 逐行
  • 对于每一行,我都附加这些行 直到遇到一个字符串变量 标签
  • 因此,使用JSOUP和post CSS过滤器 我把内容提取出来,放在屏幕上 文件
  • 提取25MB的过程平均需要88秒。。。。 所以我想表演


    如何执行提取???

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

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

    InputStream in = new BufferedInputStream(new FileInputStream(filePath),256*1024)));
    new BufferedReader(new InputStreamReader(in));
    
    如果问题是CPU,并且您有一台多核机器,那么您可以尝试将工作转移到单独的线程中

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

    但请使用StringBuilder:

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

    进一步,考虑遍历文件并创建一个只有有趣部分的地图。 我假设您没有XML,但有些东西看起来有点像它,您给出的示例是内容的公平表示

    Map<String, String> entries = new HashMap<String,String>(1000);
    StringBuilder entryData = null;
    for line in file {
      if line starts with "<docFileNo" {
         docFileNo = extract number from line;
      } else if line starts with "<div=XXXpostag>" {
         // Content of this entry starts here
         entryData = new StringBuilder();
      } else if line starts with "</html>" {
         // 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);
      }
    }
    
    Map条目=新的HashMap(1000);
    StringBuilder entryData=null;
    对于文件中的行{
    
    如果一行以“SAX解析器处理非良好格式文档的能力如何?”开头,我在问题中读到它可能不是良好格式的:(示例数据中的问题似乎是div元素未关闭。需要转换为动态。关闭的docFileNo标记也需要后缀。请参阅Joachim Sauer建议在何处对格式不好的大文件使用过滤输入流/读取器Doh tankx…我已经阅读了文章…但如何修改3G file,在标记包装器和结束包装器之后放入顶部xml定义??记住…我必须管理像3G这样的文件…我有50 TB的ile…:(…据我所知,原则是您不修改磁盘上的文件,您的程序在将数据流输入SAX解析器时修改数据流。您能举一个例子说明它如何与STAX??ora SAX解析器一起工作吗?因为我不知道如何管理数据流,以便修改文件添加xml标记,如文章中建议的那样le..tanx.3G中有多少是实际数据(jn div),有多少是结构(docfileno tags等)?因为您不需要在字符串中存储所有可复制的内容。为什么在遇到标记之前需要追加行?步骤3:不要使用字符串,而是使用stringbuilder。字符串+运算符每次都会创建一个新字符串(如果JVM没有对其进行优化,我不确定)。@extraneon的优点,我错过了它,因为我不认为不使用
    stringbuilder就可以完成它。
    :)@khachik我实际上认为,如果concat逻辑是内联写在循环中的,JVM甚至编译器会自动修复这个问题。但我不能保证这一点。如果没有优化,这将是导致OutOfMemory错误的一个很好的原因,因为在3GB时,下一个concat需要大约6GB(旧值和新值)不幸的是,我有一个2.8 GHz的奔腾4处理器。因此我加快了读取文件的过程…但我最大的问题是理解如何加快以下过程:1.将html保存在新的StringBuilder()中2.因此,高效地提取html结构中的帖子内容。我之前解释过,将帖子保存在html中的过程是使用html解析器JSOUP完成的。但我认为JSOUP在处理html时保持了很长的时间。好的。首先,所有的TANX都非常长。我已经按照您的建议修改了我的代码。一切都好了更好…不幸的是,XXXpostag不是常量,但为了检索post标记,我实现了一个过滤器,其中包含一些规则,允许我提取某些cms的内容,如blogger、wordpress..事实上还有另一个问题,那就是应用一个规则:1.识别cms生成器中的post标记。1.1识别cms生成器,正在寻找用于提取内容的任务的规则。所有cms的规则都在xml中。我的疑问是,与规则的字节相比,将所有cms规则转换为字节和…xml中的所有标记是否更昂贵。。
    Map<String, String> entries = new HashMap<String,String>(1000);
    StringBuilder entryData = null;
    for line in file {
      if line starts with "<docFileNo" {
         docFileNo = extract number from line;
      } else if line starts with "<div=XXXpostag>" {
         // Content of this entry starts here
         entryData = new StringBuilder();
      } else if line starts with "</html>" {
         // 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);
      }
    }