如何将Iterator [String]转换为Reader实例进行解析?

时间:2016-08-19 16:21:55

标签: java scala parsing iterator

我有内存问题,我想知道解析内存占用率低的文件的最佳方法是什么。现在我有了这个,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)

2 个答案:

答案 0 :(得分:0)

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

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

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

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

答案 1 :(得分:0)

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