如何在Scala中读取资源文件夹中的文件?

w1e3prcc  于 2023-02-12  发布在  Scala
关注(0)|答案(7)|浏览(326)

我有一个文件夹结构如下:

- 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
    }
  }
}
7fyelxc5

7fyelxc51#

Scala中的资源与Java中的资源工作方式完全相同,最好遵循 *Java最佳实践 *,将所有资源放在src/main/resourcessrc/test/resources中。
文件夹结构示例:

testing_styles/
├── build.sbt
├── src
│   └── main
│       ├── resources
│       │   └── readme.txt

Scala 2.12.x和2.13.x阅读资源

要读取资源,对象Source提供方法fromResource

import scala.io.Source
val readmeText : Iterator[String] = Source.fromResource("readme.txt").getLines

阅读2.12之前的资源(由于jar兼容性,我仍然喜欢)

要读取资源,可以使用getClass.getResourcegetClass.getResourceAsStream

val stream: InputStream = getClass.getResourceAsStream("/readme.txt")
val lines: Iterator[String] = scala.io.Source.fromInputStream( stream ).getLines

更好的错误反馈(2.12.x和2.13.x)

要避免不可调试的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))
 }

很高兴知道

请记住,当资源是jar的一部分时,getResourceAsStream也可以正常工作,getResource返回的URL通常用于创建文件,但可能会导致出现问题。
生产中##
在生产代码中,我建议确保再次关闭源代码。

k5ifujac

k5ifujac2#

对于Scala〉= 2.12,使用Source.fromResource

scala.io.Source.fromResource("located_in_resouces.any")
sdnqo3pr

sdnqo3pr3#

Scala的一行程序解决方案〉= 2.12

val source_html = Source.fromResource("file.html").mkString

重要摘自评论(感谢@anentropic):对于Source.fromResource,您不需要在开头加上正斜杠。

iibxawm4

iibxawm44#

import scala.io.Source

object Demo {

  def main(args: Array[String]): Unit = {

    val ipfileStream = getClass.getResourceAsStream("/folder/a-words.txt")
    val readlines = Source.fromInputStream(ipfileStream).getLines
    readlines.foreach(readlines => println(readlines))

  }

}
at0kjp5o

at0kjp5o5#

所需的文件可以从scala的resource文件夹中访问,如下所示

val file = scala.io.Source.fromFile(s"src/main/resources/app.config").getLines().mkString
qnzebej0

qnzebej06#

对于Scala 2.11,如果getLines没有完全按照您的要求执行,您还可以将文件从jar复制到本地文件系统。
下面是一个代码片段,它从/resources读取二进制的google.p12格式API密钥,将其写入/tmp,然后使用文件路径字符串作为spark-google-spreadsheets写入的输入。
sbt-native-packagersbt-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}")
ozxc1zmp

ozxc1zmp7#

“resources”文件夹必须在源代码根目录下。如果使用intellj,请检查左侧项目文件夹中的蓝色文件夹。例如AppName/src/main/scala或Project/scala/../main/etc。
如果使用val stream: InputStream = getClass.getResourceAsStream("/readme.txt"),不要忘记“/”(正斜杠),给定readme.txt是资源中的文件

相关问题