Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 使用Source.fromResource从文件读取时处理NullPointerException_Scala - Fatal编程技术网

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)
其行为与此相同。我甚至需要从
资源
文件夹中读取更多内容,因此如果文件存在,这将不起作用。