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