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

답변:


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 이전의 리소스 읽기 (항아리 호환성으로 인해 여전히 좋아함)

리소스를 읽으려면 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))
 }

~ 알아 둘만 한

마음에 계속 같이 getResourceAsStream이 자원이의 일부인 경우에도 벌금을 작동 항아리 , 의 getResource 종종이 문제가 발생할 수있는 파일을 생성하는 데 사용되는 URL을 반환합니다.

생산 중

프로덕션 코드에서 소스가 다시 닫혔는지 확인하는 것이 좋습니다.


getResource를 사용하여 파일로 변환하면 어떤 종류의 문제가 발생할 수 있습니까? 링크를 제공 할 수 있습니까?
akauppi

2
: 일부 circumstanceas 널 포인터에서 stackoverflow.com/questions/941754/...
안드레아스 노이만

이 코드는 아마도 getResourceAsStream에 대한 열린 핸들러를 떠날 것입니다.
Sisso

3
그나마 잊지 close소스
기욤 한꺼번에에게

1
감사! Nicer 오류 피드백 (2.12.x) 섹션 에서 Byt 유형이 일치하지 않습니다 . 그리고 메모리 누수는 어떻습니까? 자원을 닫아야하지 않습니까?
Albert Bikeev

30

Scala> = 2.12의 경우 다음을 사용하십시오 Source.fromResource.

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

13
중요 :와 함께 사용 Source.fromResource하는 초기 슬래시를 넣지 마십시오 getResourceAsStream.
vossad01

6
그리고 이것은 2.12+입니다
rbellamy

버전 2.10은 어떻습니까?
Jaydev

12

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

대한 스칼라 2.11 getLines 정확히하지 않는 경우, 당신은 또한 로컬 파일 시스템에 항아리 밖으로 파일을 복사 할 수 있습니다 원하는.

다음은 / resources에서 바이너리 google .p12 형식 API 키를 읽고 / tmp에 쓴 다음 파일 경로 문자열을 spark-google-spreadsheets write에 대한 입력으로 사용하는 스 니핏입니다 .

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.