Làm cách nào để đọc tệp từ thư mục tài nguyên trong Scala?


112

Tôi có cấu trúc thư mục như dưới đây:

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

và trong các thư mục đó, tôi có các tệp của mình mà tôi phải đọc. Đây là mã:

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

tại sao câu trả lời được cung cấp bởi Andreas Neumann không được chấp nhận nếu bạn có bất kỳ câu hỏi tiếp theo nào, vui lòng bình luận về nó. -1.
Vishrant

Câu trả lời:


201

Tài nguyên trong Scala hoạt động chính xác như trong Java. Tốt nhất là làm theo các phương pháp hay nhất của Java và đặt tất cả tài nguyên vào src/main/resourcessrc/test/resources.

Cấu trúc thư mục mẫu:

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

Scala 2.12.x && 2.13.x đọc tài nguyên

Để đọc tài nguyên, đối tượng Nguồn cung cấp phương thức fromResource .

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

đọc tài nguyên trước 2.12 (vẫn là mục yêu thích của tôi do khả năng tương thích với jar)

Để đọc tài nguyên, bạn có thể sử dụng getClass.getResourcegetClass.getResourceAsStream .

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

phản hồi lỗi đẹp hơn (2.12.x && 2.13.x)

Để tránh các NPE Java không thể gỡ lỗi, hãy xem xét:

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

tốt để biết

Hãy nhớ rằng getResourceAsStream cũng hoạt động tốt khi tài nguyên là một phần của jar , getResource , trả về một URL thường được sử dụng để tạo tệp có thể dẫn đến sự cố ở đó.

trong sản xuất

Trong mã sản xuất, tôi đề nghị đảm bảo rằng nguồn đã được đóng lại.


Loại sự cố nào có thể xảy ra nếu sử dụng getResource và biến nó thành một Tệp? bạn có thể cung cấp một liên kết?
akauppi

2
Trong một số trường hợp, con trỏ rỗng: stackoverflow.com/questions/941754/…
Andreas Neumann,

Mã này có thể để lại trình xử lý mở cho getResourceAsStream.
Sisso

3
đừng quên closenguồn
Guillaume Massé

1
Cảm ơn! Loại byte không khớp trong phần phản hồi lỗi Nicer (2.12.x) . Và những gì về rò rỉ bộ nhớ? Không nên đóng tài nguyên?
Albert Bikeev

30

Đối với Scala> = 2.12, sử dụng Source.fromResource:

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

13
Quan trọng: với Source.fromResourcebạn, không đặt dấu gạch chéo ban đầu về phía trước mà bạn có getResourceAsStream.
vossad01 09/12/16

6
Và lưu ý rằng đây là 2,12+
rbellamy

những gì về phiên bản 2.10?
Jaydev

11

Giải pháp Onliner cho 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))

  }

}

nhập mô tả hình ảnh ở đây

EDIT: Ghi có cho tác giả gốc. Tham khảo toàn bộ blog tại đây


Khi bạn sao chép từ một trang web, vui lòng đăng liên kết đến tác giả gốc. Cung cấp tín dụng khi nó đến hạn. Tham khảo: fruzenshtein.com/scala-working-with-resources-folders-files
ForeverLearner

2

Đối với Scala 2.11 , nếu getLines không thực hiện chính xác những gì bạn muốn, bạn cũng có thể sao chép tệp ra khỏi jar vào hệ thống tệp cục bộ.

Đây là một đoạn trích đọc khóa API định dạng google .p12 nhị phân từ / resources, ghi nó vào / tmp, sau đó sử dụng chuỗi đường dẫn tệp làm đầu vào để ghi bảng tính spark-google .

Trong thế giới của sbt-native-packagersbt-assembly , việc sao chép vào local cũng rất hữu ích với các bài kiểm tra tệp nhị phân có quy mô lớn nhất. Chỉ cần đưa chúng ra khỏi tài nguyên vào cục bộ, chạy thử nghiệm và sau đó xóa.

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

Tệp yêu cầu có thể được truy cập như bên dưới từ thư mục tài nguyên trong scala

val file = scala.io.Source.fromFile(s"src/main/resources/app.config").getLines().mkString
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.