在Spark中讀寫文本文件很容易。當我們將一個文本文件讀取爲RDD時,輸入的每一行都會成爲RDD的一個元素。也可以將多個完整的文本文件一次性讀取爲一個pairRDD,其中鍵是文件名,值是文件內容。
1、讀取文本文件
只需要使用文件路徑作爲參數調用SparkContext中的textFile()函數,就可以讀取一個文本文件,如下例。如果要控制分區數的話,可以指定minPartitions。
JavaRDD<String> input = sc.textFile("file:///home/holden/repos/spark/README.md");
如果多個輸入文件以一個包含數據所有部分的目錄的形式出現,可以用兩種方式來處理。可以仍使用textFile函數,傳遞目錄作爲參數,這樣它會把各部分都讀取到RDD中。有時候有必要知道數據的各部分分別來自哪個文件(比如將鍵放在文件名中的時間數據),有時候則希望同時處理整個文件。如果文件足夠小,那麼可以使用SparkContext.wholeTextFiles()方法,該方法會返回一個pairRDD,其中鍵是輸入文件的文件名。
wholeTextFiles()在每個文件表示一個特定時間段內的數據時非常有用。如果有表示不同階段銷售數據的文件,則可以很容易地求出每個階段地平均值。
val input = sc.wholeTextFiles("file://home/holden/salesFiles")
val result = input.mapValues{y =>
val nums = y.split(" ").map(x => x.toDouble)
nums.sum / nums.size.toDouble
}
咱啥也不說了,Java的實現複雜,且性能不如scala。我也很無奈,我也不敢問。。。
2、保存文本文件
輸出文本文件也相當簡單。下例演示的saveAsTextFile()方法接收一個路徑,並將RDD中的內容都輸入到路徑對應的文件中。Spark將傳入的路徑作爲目錄對待,會在那個目錄下輸出多個文件。這樣,Spark就可以從多個節點上並行輸出了。在這個方法中,我們不能控制數據的哪一部分輸出到哪個文件中,不過有些輸出格式支持控制。
/**
* @author DKing
* @description
* @date 2019/6/16
*/
public class TextFileTest {
public static void main(String[] args) {
SparkConf conf = new SparkConf().setMaster("local").setAppName("TextFile");
JavaSparkContext sc = new JavaSparkContext(conf);
JavaRDD<String> lines = sc.textFile("");
lines.saveAsTextFile("");
}
}