从资源目录读取文件的Scala问题 [英] scala issue with reading file from resources directory
问题描述
我写了这样的东西来从资源目录读取文件:
I wrote something like this to read file from resource directory:
val filePath = MyClass.getClass.getResource("/myFile.csv")
val file = filePath.getFile
println(file)
CSVReader.open(file)
我得到的结果是这样的:
and the result I got was something like this:
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)中运行相同的代码,则没有问题并且打印到控制台的路径是:
Whereas, if I run the same code in IDE(Intellij), no issues and the path printed to console is:
/path/to/project/my_module/target/scala-2.11/classes/myFile.csv
仅供参考,它是一个包含几个模块的多构建项目,我使用 sbt assembly
FYI, its a multi build project with a couple of modules and I build the jars using sbt assembly
推荐答案
与 Scala 或 SBT 相比,这更多地与 Java 或 JVM 本身相关.
This is more related to Java or the JVM itself than to Scala or SBT.
从 IDE 和命令行(或在 IDE 外部)运行应用程序是有区别的.方法 getClass.getResource(...)
尝试在 current 类路径中查找资源 URL,这是主要区别.
There is a difference when running your application from the IDE vs the command line (or outside the IDE). The method getClass.getResource(...)
attempts to find the resource URL in the current classpath, and that's the key difference.
如果你查看 URL 本身,你会发现在第一种情况下你有一个 my_module-assembly-0.1.jar!
位,这意味着 URL 实际上指向内容JAR 文件,而不是可从文件系统访问的文件.
If you look at the URL itself, you will find that in the first case you have a my_module-assembly-0.1.jar!
bit in it, meaning that URL is actually pointing towards the contents of the JAR, not to a file accessible from the file system.
在您的 IDE 中,您的类路径将包括磁盘上的实际文件,来自源文件夹,因为 IDE 假定没有任何 JAR 文件本身.因此,当获取由 getClass.getResource(...)
给出的 URL 时,您的 URL 中没有 my_module-assembly-0.1.jar!
位.
From inside your IDE your class path will include the actual files on disk, from the source folders, because the IDE assumes that there is not any JAR file itself. So when obtaining the URL given by getClass.getResource(...)
you have an URL that does not have the my_module-assembly-0.1.jar!
bit in it.
由于您想读取文件的内容,您可能需要执行一个 getClass.getResourceAsStream(...)
.这将为您提供一个 InputStream
,无论您是在 IDE 中还是在其他任何地方,您都可以使用它来读取内容.
Since you want to read the contents of the file, you may want to do a getClass.getResourceAsStream(...)
. That will give you an InputStream
that you can use to read the contents regardless you are in the IDE or anywhere else.
您的 CSVReader
类可能有一个方法,允许它从 InputStream
或 Reader
或类似的东西读取数据.
Your CSVReader
class may have a method that allows it read the data from an InputStream
or a Reader
or something similar.
正如 Luis Miguel Mejia Suarez,一种更符合 Scala 习惯的从类路径读取文件的方法是使用 Source.fromResource
方法.这将返回一个 BufferedSource
,然后可用于读取文件内容.
As pointed out by Luis Miguel Mejia Suarez, a more Scala idiomatic way of reading files from your class path is using the Source.fromResource
method. This will return a BufferedSource
that then can be used to read the file contents.
这篇关于从资源目录读取文件的Scala问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!