如何从 Scala 的资源文件夹中读取文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27360977/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to read files from resources folder in Scala?
提问by Pradip Karad
I have a folder structure like below:
我有一个如下所示的文件夹结构:
- main
-- java
-- resources
-- scalaresources
--- commandFiles
and in that folders I have my files that I have to read. Here is the code:
在那个文件夹中,我有我必须阅读的文件。这是代码:
def readData(runtype: String, snmphost: String, comstring: String, specificType: String): Unit = {
val realOrInvFile = "/commandFiles/snmpcmds." +runtype.trim // these files are under commandFiles folder, which I have to read.
try {
if (specificType.equalsIgnoreCase("Cisco")) {
val specificDeviceFile: String = "/commandFiles/snmpcmds."+runtype.trim+ ".cisco"
val realOrInvCmdsList = scala.io.Source.fromFile(realOrInvFile).getLines().toList.filterNot(line => line.startsWith("#")).map{
//some code
}
val specificCmdsList = scala.io.Source.fromFile(specificDeviceFile).getLines().toList.filterNot(line => line.startsWith("#")).map{
//some code
}
}
} catch {
case e: Exception => e.printStackTrace
}
}
}
回答by Andreas Neumann
Resources in Scala work exactly as they do in Java.
It is best to follow the Java best practicesand put all resources in src/main/resourcesand src/test/resources.
Scala 中的资源与 Java 中的资源完全一样。最好遵循Java 最佳实践并将所有资源放入src/main/resources和src/test/resources.
Example folder structure:
示例文件夹结构:
testing_styles/
├── build.sbt
├── src
│?? └── main
│?? ├── resources
│?? │?? └── readme.txt
Scala 2.12.x && 2.13.x reading a resource
Scala 2.12.x && 2.13.x 读取资源
To read resources the object Sourceprovides the method fromResource.
为了读取资源,对象Source提供了方法fromResource。
import scala.io.Source
val readmeText : Iterator[String] = Source.fromResource("readme.txt").getLines
reading resources prior 2.12 (still my favourite due to jar compatibility)
阅读 2.12 之前的资源(由于 jar 兼容性仍然是我的最爱)
To read resources you can use getClass.getResourceand getClass.getResourceAsStream.
要读取资源,您可以使用getClass.getResource和getClass.getResourceAsStream。
val stream: InputStream = getClass.getResourceAsStream("/readme.txt")
val lines: Iterator[String] = scala.io.Source.fromInputStream( stream ).getLines
nicer error feedback (2.12.x && 2.13.x)
更好的错误反馈(2.12.x && 2.13.x)
To avoid undebuggable Java NPEs, consider:
为避免无法调试的 Java NPE,请考虑:
import scala.util.Try
import scala.io.Source
import java.io.FileNotFoundException
object Example {
def readResourceWithNiceError(resourcePath: String): Try[Iterator[String]] =
Try(Source.fromResource(resourcePath).getLines)
.recover(throw new FileNotFoundException(resourcePath))
}
good to know
很高兴知道
Keep in mind that getResourceAsStreamalso works fine when the resources are part of a jar, getResource, which returns a URL which is often used to create a file can lead to problems there.
请记住,当资源是jar 的一部分时,getResourceAsStream也可以正常工作,getResource返回一个通常用于创建文件的 URL 可能会导致问题。
in Production
生产中
In production code I suggest to make sure that the source is closed again.
在生产代码中,我建议确保再次关闭源代码。
回答by Mohsen Kashi
For Scala >= 2.12, use Source.fromResource:
对于 Scala >= 2.12,使用Source.fromResource:
scala.io.Source.fromResource("located_in_resouces.any")
回答by freedev
Onliner solution for Scala >= 2.12
Scala >= 2.12 的在线解决方案
val source_html = Source.fromResource("file.html").mkString
回答by Sri
import scala.io.Source
object Demo {
def main(args: Array[String]): Unit = {
val fileStream = getClass.getResourceAsStream("/json-sample.js")
val lines = Source.fromInputStream(fileStream).getLines
lines.foreach(line => println(line))
}
}
EDIT: Credit to the original author. Refer the full blog here
编辑:感谢原作者。请参阅此处的完整博客
回答by Tony Fraser
For Scala 2.11, if getLines doesn't do exactly what you want you can also copy the a file out of the jar to the local file system.
对于Scala 2.11,如果 getLines 没有完全按照您的要求执行,您还可以将 a 文件从 jar 复制到本地文件系统。
Here's a snippit that reads a binary google .p12 format API key from /resources, writes it to /tmp, and then uses the file path string as an input to a spark-google-spreadsheetswrite.
这是一个片段,它从 /resources 读取二进制 google .p12 格式的 API 密钥,将其写入 /tmp,然后使用文件路径字符串作为spark-google-spreadsheets write的输入。
In the world of sbt-native-packagerand sbt-assembly, copying to local is also useful with scalatest binary file tests. Just pop them out of resources to local, run the tests, and then delete.
在sbt-native-packager和sbt-assembly的世界中,复制到本地对于 scalatest 二进制文件测试也很有用。只需将它们从资源中弹出到本地,运行测试,然后删除。
import java.io.{File, FileOutputStream}
import java.nio.file.{Files, Paths}
def resourceToLocal(resourcePath: String) = {
val outPath = "/tmp/" + resourcePath
if (!Files.exists(Paths.get(outPath))) {
val resourceFileStream = getClass.getResourceAsStream(s"/${resourcePath}")
val fos = new FileOutputStream(outPath)
fos.write(
Stream.continually(resourceFileStream.read).takeWhile(-1 !=).map(_.toByte).toArray
)
fos.close()
}
outPath
}
val filePathFromResourcesDirectory = "google-docs-key.p12"
val serviceAccountId = "[something]@drive-integration-[something].iam.gserviceaccount.com"
val googleSheetId = "1nC8Y3a8cvtXhhrpZCNAsP4MBHRm5Uee4xX-rCW3CW_4"
val tabName = "Favorite Cities"
import spark.implicits
val df = Seq(("Brooklyn", "New York"),
("New York City", "New York"),
("San Francisco", "California")).
toDF("City", "State")
df.write.
format("com.github.potix2.spark.google.spreadsheets").
option("serviceAccountId", serviceAccountId).
option("credentialPath", resourceToLocal(filePathFromResourcesDirectory)).
save(s"${googleSheetId}/${tabName}")
回答by Dileep Dominic
The required file can be accessed as below from resource folder in scala
可以从scala的资源文件夹中访问所需的文件,如下所示
val file = scala.io.Source.fromFile(s"src/main/resources/app.config").getLines().mkString


