最近在處理一個log時,發現出現亂碼,想起來自己要處理的log編碼是GB18030,而hadoop默認的編碼格式是UTF-8,所以需要轉化。在讀取數據的時候就是GBK轉化為UTF-8,在處理完成后寫入結果時,將UTF-8 轉化為GBK(我這個log是GB18030)
map輸入時,將GB18030轉UTF-8
public void map(Object key, Text value, Context context) throws IOException, InterruptedException {
value = getTextToUTF8(value, "GB18030");// 轉碼 為UTF-8
而getTextToUTF8函數如下:
public Text getTextToUTF8(Text text, String encoding) {
String value = null; // Java String 是 Unicode 形式.
try {
value = new String(text.getBytes(), 0, text.getLength(), encoding); // text.getBytes()得到的byte數組是原始數據的byte數組,是原始編碼.
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return new Text(value);
}
Reduce輸出時,將UTF-8轉化為 GB18030
在網上找資料的時候,有些網友說在TextOutputFormat將utf-8寫死了,如果在Reduce階段,想將結果編碼為GBK,需要重寫 TextOutputFormat
但是發現,其實也不需要,直接轉化也行的,方法如下
private LongWritable result = new LongWritable();
public void reduce(Text key, Iterable<LongWritable> values,Context context) throws IOException, InterruptedException {
long sum = 0;
for (LongWritable val : values) {
sum += val.get();
}
result.set(sum);
context.write(new Text(key.toString().getBytes("GB18030")), result);
//context.write(key, result);
}
處理完畢,發現結果不是亂碼,可見無需重寫TextOutputFormat類也行。
參考文獻
http://note.youdao.com/share/?id=04678102d70bae8334b26df2c9c4a961&type=note#/