Scalaのリソースフォルダーからファイルを読み取る方法は?


112

以下のようなフォルダ構造があります。

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

Andreas Neumannによって提供された回答がフォローアップの質問がある場合に受け入れられなかった理由それについてコメントしてください。-1。
Vishrant 2018

回答:


201

Scalaのリソースは、Javaのリソースとまったく同じように機能します。Javaのベストプラクティスに従い、すべてのリソースをsrc/main/resourcesとに配置することをお勧めしsrc/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.getResourceおよびgetClass.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))
 }

知ってよかった

ことを覚えておいてくださいgetResourceAsStreamはまた、資源がの一部であるとき、正常に動作のgetResource頻繁にファイルを作成するために使用されるURLを返し、そこに問題を引き起こす可能性が。

生産中

量産コードでは、ソースが再び閉じられていることを確認することをお勧めします。


getResourceを使用してファイルに変換すると、どのような問題が発生する可能性がありますか?リンクを提供してもらえますか?
akauppi 2016年

2
いくつかのcircumstanceasでNULLポインタ:stackoverflow.com/questions/941754/...
アンドレアス・ノイマン

このコードは、おそらくgetResourceAsStreamのオープンハンドラーを残しています。
Sisso 2017年

3
closeソースを忘れないでください
GuillaumeMassé2017

1
ありがとう!Byt型は、より適切なエラーフィードバック(2.12.x)セクションで一致しません。そして、メモリリークはどうですか?リソースを閉じてはいけませんか?
Albert Bikeev

30

Scala> = 2.12の場合Source.fromResource

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

13
重要:で使用Source.fromResourceする最初のスラッシュを付けないでくださいgetResourceAsStream
vossad01 16

6
そして、これは2.12+であることに注意してください
rbellamy

バージョン2.10はどうですか?
Jaydev 2018年

11

Scalaのオンラインソリューション> = 2.12

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

4
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))

  }

}

ここに画像の説明を入力してください

編集:元の作者へのクレジット。ブログ全体をここで参照してください


ウェブサイトからコピーする場合は、元の作者へのリンクを投稿してください。それが期日であると認めてください。参照:fruzenshtein.com/scala-working-with-resources-folders-files
ForeverLearner

2

以下のためのScala 2.11 getLinesが正確に行わない場合、あなたはまた、ローカルファイルシステムに瓶の外にファイルをコピーすることができます何をしたいです。

これは、/ 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}")

2

必要なファイルは、scalaのリソースフォルダーから以下のようにアクセスできます。

val file = scala.io.Source.fromFile(s"src/main/resources/app.config").getLines().mkString
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.