我写了这样的东西来从资源目录中读取文件:
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
答案 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
类可能具有允许从InputStream
或Reader
或类似的东西中读取数据的方法。
编辑:正如Luis Miguel Mejia Suarez所指出的那样,从类路径读取文件的一种Scala惯用方式是使用Source.fromResource
method。这将返回一个BufferedSource
,然后可以将其用于读取文件内容。