For your question 1, short answer: use Source.fromFile("build.sbt").getLines()
directly without using bufferedSource
, because bufferedSource
and lines
sharing same InputStream
, in debug time, maybe the index has changed by toString
Full Explanation:
This is caused by toString method has changed the Stream
's index that shared between lines
and bufferedSource
in the debug time , As we know when IDE stop in the breakpoint, it will invoke
variable
toString
methods. like for lines
and bufferedSource
variables, it will invoke Iterator.toString
, output like:
override def toString = (if (hasNext) "non-empty" else "empty")+" iterator"
> bufferedSource: non-empty iterator
> lines: non-empty iterator
As the above toString
method, it will invoke hasNext
firstly, this means it will invoke iter.hasNext in BufferedSource
, but there is a problem for BufferedSource.iter
:
override lazy val iter = (
Iterator
continually (codec wrap charReader.read())
takeWhile (_ != -1)
map (_.toChar)
)
when check hasNext
it will read a character from InputStream
. but this InputStream
is sharing with BufferedLineIterator
.
for val lines = bufferedSource.getLines()
is creating new BufferedLineIterator
from the BufferedSource
by BufferedSource.decachedReader with sharing same InputStream
between BufferedSource
.
So if we have invoked hasNext
method on BufferedSource
, it will change the index on BufferedLineIterator
.
Below is an example to demonstrate this:
//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._
As the above example, we manually invoke hasNext
method, so the Stream
index has changed to next.
And for when we using IDE to debug, it invokes toString
randomly, so it maybe cause the second character missing by debug in:
https://github.com/scala/scala/blob/2.13.x/src/library/scala/io/BufferedSource.scala#L55