Scala Source.fromFile(fileName).getLines()。next()错过了字符串行中的第二个字符

时间:2017-12-10 11:13:27

标签: scala file iterator

以下是代码:

val bufferedSource = Source.fromFile("build.sbt")
val lines = bufferedSource.getLines()
bufferedSource.close()
ptintln(lines.next())

build.sbt文件有这样的内容:

name := "timeSeriesMerge"

version := "0.1"

scalaVersion := "2.11.8"

lines中调试程序时,我得到的字符串中缺少第二个字符:

"nme := "timeSeriesMerge""

任何人都可以解释这是怎么回事?它错过了字符串中的第二个字符。问题出在哪儿?它错过了第一行的第二个字符。

如果有人能解释为什么这段代码会抛出,那也很酷:

java.io.IOException: Stream Closed

2 个答案:

答案 0 :(得分:3)

对于您的问题1,简短回答:直接使用Source.fromFile("build.sbt").getLines()而不使用bufferedSource,因为bufferedSourcelines在调试时间内共享相同的InputStream,也许索引已经改变了toString

完整说明:

这是由 toString 方法更改了调试时间内Streamlines之间共享的bufferedSource索引引起的strong>,正如我们所知,当 IDE 停在断点时,它将invoke variable toString个方法。与linesbufferedSource变量一样,它会调用Iterator.toString,输出如下:

override def toString = (if (hasNext) "non-empty" else "empty")+" iterator"
> bufferedSource: non-empty iterator
> lines: non-empty iterator

作为上述toString方法,它首先会调用hasNext,这意味着它会在BufferedSource中调用iter.hasNext,但BufferedSource.iter存在问题}:

  override lazy val iter = (
    Iterator
    continually (codec wrap charReader.read())
    takeWhile (_ != -1)
    map (_.toChar)
  )

当检查hasNext时,它会从InputStream读取一个字符。但此InputStreamBufferedLineIterator共享。

val lines = bufferedSource.getLines()

正在BufferedLineIterator BufferedSource创建新的hasNext,共享BufferedSource.decachedReader

因此,如果我们在BufferedSource上调用BufferedLineIterator方法,则会更改 //file content: import Settings._ val bufferedSource: BufferedSource = Source.fromFile("build.sbt") val lines = bufferedSource.getLines() bufferedSource.hasNext val str = lines.next() println(str) > mport Settings._ 上的索引。

以下是一个证明这一点的例子:

hasNext

如上例所示,我们手动调用Stream方法,因此toString索引已更改为next。

当我们使用 IDE 进行调试时,它会随机调用public class HelloWorld { protected int num = 12; public void callme() { System.out.print(this.num); } public static void main(String[] args) { HelloWorld myObject1 = new HelloWorld(); myObject1.callme(); OtherClass myObject2 = new OtherClass(); myObject2.callme(); } } public class OtherClass extends HelloWorld { protected int num = 14; } ,因此可能导致调试中缺少第二个字符:

InputStream between BufferedSource

答案 1 :(得分:2)

在这里,你正在打电话"接下来"在流关闭后在Iterator上。

只有在完成使用后才能关闭流。 因此,正确的陈述顺序应为

    println(lines.next())
    bufferedSource.close()

此外,如果要迭代整个文件,则需要在循环内调用next。你可以尝试 -

    for(line <- lines){
      println(line)
    }