【问题标题】:How to transform Iterator[String] into a Reader instance for parsing?如何将 Iterator[String] 转换为 Reader 实例进行解析?
【发布时间】:2016-12-26 21:21:59
【问题描述】:

我有内存问题,我想知道最好的方法是解析低内存占用的文件。现在我有这个,一个 Iterator[String]

val myIterator: Iterator[String] = io.Source.fromURL("http://somewebsite.com/download/bigFile.txt").getLines().filter(isValidInput)

现在我要解析它。

val result = MyParser.parseAll(MyParser.line, ???)

它需要java.io.Reader,我已经尝试了StringReader,但这会杀死我的电脑。有没有办法将 Iterator 转换为 Reader?

我也尝试了以下,但解析后的结果是 0。所以我想我做错了什么。

import java.io.{BufferedReader, InputStreamReader}
import scala.collection.JavaConverters._

val stream: InputStream = new SequenceInputStream({
  val i = myIterator map { s => new ByteArrayInputStream(s.getBytes("UTF-8")) }
  i.asJavaEnumeration
})
val in = new BufferedReader(new InputStreamReader(stream))

val result = MyParser.parseAll(MyParser.line, in)

【问题讨论】:

  • new InputStreamReader(new URL("http://...").openStream)
  • 我在其他地方的代码中使用了迭代器,所以这就是我第二次尝试解析它时的问题。它试图解析,但我的电脑在解析时死机了。这也可能无法解决问题。
  • @Dima 我在解析之前做了一些过滤。这样做的一个原因是丢弃所有不需要的行并使解析器不会过于复杂。有没有办法从 List[String] 或 Iterator[String] 创建 InputStreamReader、BufferedReader 等?
  • 嗯,这就是你的第二个 sn-p 所做的(只要你不使用迭代器)。看起来相当倒退,但是……不管怎样都行。

标签: java scala parsing iterator


【解决方案1】:

您可以尝试使用 Scala 提供的PagedSeqReader

import scala.util.parsing.input.PagedSeqReader
import scala.collection.immutable.PagedSeq 

MyParser.parseAll(
  MyParser.line, 
  new PagedSeqReader(PagedSeq.fromLines(myIterator)))

请注意,由于回溯,使用 Scala 的 parsing-combinators 库进行解析可能需要随机访问。我不知道PagedSeq 处理这个问题的效果如何,如果它最终不会尝试将整个Iterator 加载到内存中,即使使用不回溯的解析器也是如此。在那种情况下,做你想做的事情可能是不可能的。

【讨论】:

    【解决方案2】:

    如果您的解析器一次只能解析一行,请执行以下操作:myIterator map { l => MyParser.parseAll(MyParser.line, l) } 以获取 Iterator[ParserResult[X]]

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-14
      • 1970-01-01
      • 2010-09-23
      相关资源
      最近更新 更多