首页 > 解决方案 > 从资源目录读取文件的scala问题

问题描述

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

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

仅供参考,它是一个包含几个模块的多构建项目,我使用sbt assembly

标签: scalasbt

解决方案


这与 Java 或 JVM 本身有关,而不是与 Scala 或 SBT 相关。

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

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

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


由于您想读取文件的内容,您可能需要执行getClass.getResourceAsStream(...). 无论您是在 IDE 中还是在其他任何地方,这都会为您提供InputStream可以用来阅读内容的内容。

你的CSVReader类可能有一个方法,允许它从一个InputStream或一个Reader或类似的东西中读取数据。

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


推荐阅读