Scala 使用Source.fromResource从文件读取时处理NullPointerException
从不存在的文件读取时,我得到了Scala 使用Source.fromResource从文件读取时处理NullPointerException,scala,Scala,从不存在的文件读取时,我得到了Source.fromResource()方法的奇怪行为。据我所知,它应该返回null,所以我将它包装到选项中。但是当匹配它时,它被识别为Some,我得到NullPointerException ReadFromFileExample.scala: object ReadFromFileExample extends App { import scala.io.Source val sourceOpt = Option(Source.fromResour
Source.fromResource()
方法的奇怪行为。据我所知,它应该返回null
,所以我将它包装到选项中。但是当匹配它时,它被识别为Some
,我得到NullPointerException
ReadFromFileExample.scala:
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")
}
}
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")
}
}
如何解释这种行为
UPD
我错了。它应该返回类型为BufferedSource
的非null
值。但我怀疑它可以返回BufferedLineIterator
类型的值null
。我不明白它如何返回NullPointerException
而不是BufferedLineIterator
用Try(Source.fromFile(…)替换选项(Source.fromResource(…))
好的,经过深思熟虑,我得出结论,最好使用Try
而不是选项,因为它会捕获任何异常
解决方案:
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")
}
}
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")
}
}
更新
我已经弄清楚了调用getLines()
时如何获取NullPointerException
调用resource
中的方法fromResource时,在下面调用一个方法classLoader.getResourceAsStream()
。它返回InputStream
,如果文件不存在,则返回null
根据下面的stacktrace,这个InputStream
被传递到Reader
构造函数,在这里它作为要同步的对象,即lock
字段。如果它是null
,将抛出NullPointerException
Reader.java:
//...
protected Reader(Object lock) {
if (lock == null) {
throw new NullPointerException();
}
this.lock = lock;
}
//...
Stacktrace(来自我问题中的片段):
线程“main”java.lang.NullPointerException中的异常
在java.io.Reader上。(Reader.java:78)
位于java.io.InputStreamReader。(InputStreamReader.java:129)
位于scala.io.BufferedSource.reader(BufferedSource.scala:22)
位于scala.io.BufferedSource.bufferedReader(BufferedSource.scala:23)
位于scala.io.BufferedSource.charReader$lzycompute(BufferedSource.scala:33)
位于scala.io.BufferedSource.charReader(BufferedSource.scala:31)
在scala.io.BufferedSource.scala$io$BufferedSource$$decachedReader中(BufferedSource.scala:60)
位于scala.io.BufferedSource$BufferedLineIterator。(BufferedSource.scala:65)
位于scala.io.BufferedSource.getLines(BufferedSource.scala:84)
在ReadFromFileExample$.delayedEndpoint$ReadFromFileExample$1(ReadFromFileExample.scala:12)
其行为与此相同。我甚至需要从资源
文件夹中读取更多内容,因此如果文件存在,这将不起作用。