如何从Scala中的资源文件夹中读取文件?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何从Scala中的资源文件夹中读取文件?相关的知识,希望对你有一定的参考价值。
我有一个像下面的文件夹结构:
- main
-- java
-- resources
-- scalaresources
--- commandFiles
在那个文件夹中,我有我必须阅读的文件。这是代码:
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
}
}
}
Scala中的资源与Java中的资源完全相同。最好遵循Java最佳实践并将所有资源放在src/main/resources
和src/test/resources
中。
示例文件夹结构:
testing_styles/
├── build.sbt
├── src
│ └── main
│ ├── resources
│ │ └── readme.txt
Scala 2.12.x
为了读取资源,对象Source提供了fromResource方法。
import scala.io.Source
val readmeText : Iterator[String] = Source.fromResource("readme.txt").getLines
仍然可以应用先前版本中使用的方法。注意路径上的差异:"file"
vs "./file"
。
prior Versions
要读取资源,可以使用getClass.getResource和getClass.getResourceAsStream。
val stream : InputStream = getClass.getResourceAsStream("/readme.txt")
val lines = scala.io.Source.fromInputStream( stream ).getLines
请记住,当资源是jar的一部分时,getResourceAsStream也能正常工作,getResource返回一个通常用于创建文件的URL,可能会导致问题。
Nicer error feedback (2.12.x)
为了避免不可攻击的Java NPE(Java太可怕了),请考虑:
import scala.io.Source
import scala.util.Try
def niceFeedbackReadResource(resource: String): List[String] =
Try(Source.fromResource(resource).getLines.toList)
.recover(throw new FileNotFoundException(resource))
要获得有意义的FNFE。
对于生产代码,我还建议确保源再次关闭。
对于Scala> = 2.12,使用Source.fromResource
:
scala.io.Source.fromResource("located_in_resouces.any")
Onliner solution for Scala >= 2.12
val source_html = Source.fromResource("file.html").getLines().mkString("
")
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))
}
}
对于Scala 2.11,如果getLines不能完全按照您的要求执行操作,您还可以将jar文件从jar复制到本地文件系统。
这是一个从/ resources读取二进制google .p12格式API密钥的snippit,将其写入/ tmp,然后使用文件路径字符串作为spark-google-spreadsheets write的输入。
在sbt-native-packager和sbt-assembly的世界中,复制到本地对于最新的二进制文件测试也很有用。只需将它们从资源中弹出到本地,运行测试,然后删除即可。
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}")
以上是关于如何从Scala中的资源文件夹中读取文件?的主要内容,如果未能解决你的问题,请参考以下文章
应该如何修改从网络驱动器读取 5G 日志文件的 Scala 脚本以读取最后 x 行(如 Unix 中的“tail”)?
在本地文件系统(不是HDFS)中使用Scala读取Apache Spark中的文件时如何更改输入块大小[重复]