How to read files from resources folder in Scala?

前端 未结 6 923
渐次进展
渐次进展 2020-11-29 16:37

I have a folder structure like below:

- main
-- java
-- resources 
-- scalaresources
--- commandFiles 

and in that folders I have my files

相关标签:
6条回答
  • 2020-11-29 16:50
    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))
    
      }
    
    }
    
    0 讨论(0)
  • 2020-11-29 16:55

    Onliner solution for Scala >= 2.12

    val source_html = Source.fromResource("file.html").mkString
    
    0 讨论(0)
  • 2020-11-29 17:01

    Resources in Scala work exactly as they do in Java. It is best to follow the Java best practices and put all resources in src/main/resources and 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

    To read resources the object Source provides the method 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)

    To read resources you can use getClass.getResource and 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)

    To avoid undebuggable Java NPEs, consider:

    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 getResourceAsStream also 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.

    in Production

    In production code I suggest to make sure that the source is closed again.

    0 讨论(0)
  • 2020-11-29 17:01

    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.

    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-spreadsheets write.

    In the world of sbt-native-packager and 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.

    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}")
    
    0 讨论(0)
  • 2020-11-29 17:04

    The required file can be accessed as below from resource folder in scala

    val file = scala.io.Source.fromFile(s"src/main/resources/app.config").getLines().mkString
    
    0 讨论(0)
  • 2020-11-29 17:11

    For Scala >= 2.12, use Source.fromResource:

    scala.io.Source.fromResource("located_in_resouces.any")
    
    0 讨论(0)
提交回复
热议问题