从资源目录读取文件的scala问题

时间:2018-11-29 16:27:08

标签: scala sbt

我写了这样的东西来从资源目录中读取文件:

val filePath = MyClass.getClass.getResource("/myFile.csv")
val file = filePath.getFile
println(file)
CSVReader.open(file)

我得到的结果是这样的:

file:/path/to/project/my_module/src/main/resources/my_module-assembly-0.1.jar!/myFile.csv

Exception in thread "main" java.io.FileNotFoundException: file:/path/to/project/my_module/src/main/resources/my_module-assembly-0.1.jar!/myFile.csv (No such file or directory)

如果我在IDE(Intellij)中运行相同的代码,则没有问题,并且打印到控制台的路径是:

/path/to/project/my_module/target/scala-2.11/classes/myFile.csv

FYI,它是一个带有两个模块的多重构建项目,我使用sbt assembly

来构建jar。

1 个答案:

答案 0 :(得分:3)

与Scala或SBT相比,这与Java或JVM本身更相关。

从IDE和命令行(或在IDE外部)运行应用程序时有所不同。方法getClass.getResource(...)尝试在当前类路径中查找资源URL,这是关键的区别。

如果查看URL本身,您会发现在第一种情况下,其中有一个my_module-assembly-0.1.jar!位,这意味着URL实际上是指向JAR的内容,而不是指向可从其中访问的文件文件系统。

在IDE内部,您的类路径将包括源文件夹中磁盘上的实际文件,因为IDE假定本身没有任何JAR文件。因此,在获取getClass.getResource(...)给定的URL时,您所拥有的URL中没有my_module-assembly-0.1.jar!位。


由于要读取文件的内容,因此您可能需要执行getClass.getResourceAsStream(...)。这将为您提供InputStream,无论您在IDE或其他任何地方,都可以使用它来读取内容。

您的CSVReader类可能具有允许从InputStreamReader或类似的东西中读取数据的方法。

编辑:正如Luis Miguel Mejia Suarez所指出的那样,从类路径读取文件的一种Scala惯用方式是使用Source.fromResource method。这将返回一个BufferedSource,然后可以将其用于读取文件内容。