这样做的目的是为了在HDFS中的第二个位置操作和保存每个数据文件的副本。我将使用
RddName.coalesce(1).saveAsTextFile(pathName)
将结果保存到HDFS。
这就是为什么我想单独写每个文件,即使我确信性能不会那么高效。但是,我还没有确定如何将CSV文件路径列表存储到字符串数组中,然后使用单独的RDD循环遍历每个字符串。
让我们使用以下匿名示例作为HDFS源位置:
/data/email/click/date=2015-01-01/sent_20150101.csv
/data/email/click/date=2015-01-02/sent_20150102.csv
/data/email/click/date=2015-01-03/sent_20150103.csv
我知道如何使用Hadoop FS Shell列出文件路径:
HDFS DFS -ls /data/email/click/*/*.csv
我知道如何为所有数据创建一个RDD:
val sentRdd = sc.textFile( "/data/email/click/*/*.csv" )
答案 0 :(得分:8)
我还没有对它进行过彻底的测试,但这样的事情似乎有效:
import org.apache.spark.deploy.SparkHadoopUtil
import org.apache.hadoop.fs.{FileSystem, Path, LocatedFileStatus, RemoteIterator}
import java.net.URI
val path: String = ???
val hconf = SparkHadoopUtil.get.newConfiguration(sc.getConf)
val hdfs = FileSystem.get(hconf)
val iter = hdfs.listFiles(new Path(path), false)
def listFiles(iter: RemoteIterator[LocatedFileStatus]) = {
def go(iter: RemoteIterator[LocatedFileStatus], acc: List[URI]): List[URI] = {
if (iter.hasNext) {
val uri = iter.next.getPath.toUri
go(iter, uri :: acc)
} else {
acc
}
}
go(iter, List.empty[java.net.URI])
}
listFiles(iter).filter(_.toString.endsWith(".csv"))
答案 1 :(得分:1)
这最终对我有用:
import org.apache.hadoop.fs._
import org.apache.spark.deploy.SparkHadoopUtil
import java.net.URI
val hdfs_conf = SparkHadoopUtil.get.newConfiguration(sc.getConf)
val hdfs = FileSystem.get(hdfs_conf)
// source data in HDFS
val sourcePath = new Path("/<source_location>/<filename_pattern>")
hdfs.globStatus( sourcePath ).foreach{ fileStatus =>
val filePathName = fileStatus.getPath().toString()
val fileName = fileStatus.getPath().getName()
// < DO STUFF HERE>
} // end foreach loop
答案 2 :(得分:0)
sc.wholeTextFiles(path)应该有所帮助。它给出了一个rdd(filepath,filecontent)。