我需要读取存储在我的项目资源中的文件,目录是
src/main/resources/dataset/dataset.dat
。
我使用以下几行 Scala 代码从 HDFS 读取文本文件并解析为数据集对象的 Spark RDD:
// init Spark context
val conf: SparkConf = new SparkConf().setAppName("mydataset").setMaster("local")
val sc: SparkContext = new SparkContext(conf)
// read dat file
val resource = this.getClass.getClassLoader.getResource("dataset/dataset.dat")
val dsRdd: RDD[DatasetObject] = sc.textFile(resource.toString(), 1).map(line => DatasetData.parse(line))
但出现以下错误:
class java.lang.IllegalArgumentException: java.net.URISyntaxException: Relative path in absolute URI: jar:file:/grader/grader.jar!/dataset/dataset.dat
java.lang.IllegalArgumentException: java.net.URISyntaxException: Relative path in absolute URI: jar:file:/grader/grader.jar!/dataset/dataset.dat
我尝试以另一种方式读取文件,但错误不断发生:
val dsRdd: RDD[DatasetObject] = sc.textFile("src/main/resources/dataset/dataset.dat").map(line => DatasetData.parse(line))
重要: 单元测试在本地运行成功,问题出现在远程测试环境。
问题在于使用
getResource
和 textFile
,我必须使用 getResourceAsStream
和 sc.parallelize
的组合,如下所示:
def lines: List[String] = {
Option(getClass.getResourceAsStream("/dataset/dataset.dat")) match {
case None => sys.error("Please download the dataset as explained in the assignment instructions")
case Some(resource) => Source.fromInputStream(resource).getLines().toList
}
}
并解析为数据集对象的 Spark RDD
val dsRdd: RDD[DatasetObject] = sc.parallelize(lines).map(line => DatasetData.parse(line))