从不存在的文件中读取时,我发现width
方法有奇怪的行为。据我了解,它应该返回Source.fromResource()
,所以我将其包装到null
中。但是当匹配它时,它被识别为Option
,我得到Some
。
ReadFromFileExample.scala:
NullPointerException
如何解释这种行为?
UPD
我错了。它应返回类型为object ReadFromFileExample extends App {
import scala.io.Source
val sourceOpt = Option(Source.fromResource("non_existing_file.txt"))
assert (sourceOpt.isDefined) // but it should return false
sourceOpt match {
case Some(source) => source.getLines()
case None => throw new RuntimeException("Error reading from file")
}
}
的非null
值。但是我怀疑它可以返回类型BufferedSource
的值null
。我不明白它如何返回BufferedLineIterator
而不是NullPointerException
答案 0 :(得分:1)
好吧,经过深思后,我得出结论,最好使用Try
而不是Option
,因为它会捕获任何异常
解决方案:
import scala.util.{Failure, Success, Try}
object ReadFromFileExample extends App {
import scala.io.Source
Try(Source.fromResource("non_existing_file.txt").getLines()) match {
case Success(lines) => // handling lines
case Failure(e) => println(s"An error has occured, cause: $e")
}
}
更新
我已经弄清楚如何致电NullPointerException
时得到getLines()
。
调用方法fromResource
时,下面将调用方法classLoader.getResourceAsStream()
。如果文件不存在,它将返回InputStream
,即null
。
根据下面的堆栈跟踪,将此InputStream
传递到Reader
构造函数,在该构造函数中用作要同步的对象,即lock
字段。如果是null
,将抛出NullPointerException
。
Reader.java :
//...
protected Reader(Object lock) {
if (lock == null) {
throw new NullPointerException();
}
this.lock = lock;
}
//...
Stacktrace (来自我的问题摘录):
Exception in thread "main" java.lang.NullPointerException
at java.io.Reader.<init>(Reader.java:78)
at java.io.InputStreamReader.<init>(InputStreamReader.java:129)
at scala.io.BufferedSource.reader(BufferedSource.scala:22)
at scala.io.BufferedSource.bufferedReader(BufferedSource.scala:23)
at scala.io.BufferedSource.charReader$lzycompute(BufferedSource.scala:33)
at scala.io.BufferedSource.charReader(BufferedSource.scala:31)
at scala.io.BufferedSource.scala$io$BufferedSource$$decachedReader(BufferedSource.scala:60)
at scala.io.BufferedSource$BufferedLineIterator.<init>(BufferedSource.scala:65)
at scala.io.BufferedSource.getLines(BufferedSource.scala:84)
at ReadFromFileExample$.delayedEndpoint$ReadFromFileExample$1(ReadFromFileExample.scala:12)
答案 1 :(得分:0)
用Try(Source.fromFile(...))替换Option(Source.fromResource(...))
import scala.io.Source
val sourceTry = Try(Source.fromFile("non_existing_file.txt"))
sourceTry match {
case Success(source) => source.getLines()
case Failure(f) => println(f.getMessage)
}