hadoop涉及输出文本的默认输出编码统一用没有BOM的UTF-8的形式,但是对于中文的输出window系统默认的是GBK,有些格式文件例如CSV格式的文件用excel打开输出编码为没有BOM的UTF-8文件时,输出的结果为乱码,只能由UE或者记事本打开才能正常显示。因此将hadoop默认输出编码更改为GBK成为非常常见的需求。
自定义 TextOutputFormat.class

package com.ljt.hdfs;import java.io.DataOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.compress.CompressionCodec;
import org.apache.hadoop.io.compress.GzipCodec;
import org.apache.hadoop.mapreduce.RecordWriter;
import org.apache.hadoop.mapreduce.TaskAttemptContext;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.ReflectionUtils;
/*** * <p>Title:hadoop MapReduce 输出结果中文乱码解决</p>* <p> 功能描述:: </p>* <p>Company: adteach </p> * @author  刘建涛 * * @date    2017年7月19日下午4:37:41* @version 1.0*/@InterfaceAudience.Public
@InterfaceStability.Stable
public class TextOutputFormat<K, V> extends FileOutputFormat<K, V> {public static String SEPERATOR = "mapreduce.output.textoutputformat.separator";protected static class LineRecordWriter<K, V>extends RecordWriter<K, V> {private static final String utf8 = "UTF-8";  // 将UTF-8转换成GBK private static final byte[] newline;static {try {newline = "\n".getBytes(utf8);} catch (UnsupportedEncodingException uee) {throw new IllegalArgumentException("can't find " + utf8 + " encoding");}}protected DataOutputStream out;private final byte[] keyValueSeparator;public LineRecordWriter(DataOutputStream out, String keyValueSeparator) {this.out = out;try {this.keyValueSeparator = keyValueSeparator.getBytes(utf8);} catch (UnsupportedEncodingException uee) {throw new IllegalArgumentException("can't find " + utf8 + " encoding");}}public LineRecordWriter(DataOutputStream out) {this(out, "\t");}/*** Write the object to the byte stream, handling Text as a special* case.* @param o the object to print* @throws IOException if the write throws, we pass it on*/private void writeObject(Object o) throws IOException {if (o instanceof Text) {Text to = (Text) o;   // 将此行代码注释掉out.write(to.getBytes(), 0, to.getLength());  // 将此行代码注释掉} else { // 将此行代码注释掉      out.write(o.toString().getBytes(utf8));}}public synchronized void write(K key, V value)throws IOException {boolean nullKey = key == null || key instanceof NullWritable;boolean nullValue = value == null || value instanceof NullWritable;if (nullKey && nullValue) {return;}if (!nullKey) {writeObject(key);}if (!(nullKey || nullValue)) {out.write(keyValueSeparator);}if (!nullValue) {writeObject(value);}out.write(newline);}public synchronized void close(TaskAttemptContext context) throws IOException {out.close();}}public RecordWriter<K, V> getRecordWriter(TaskAttemptContext job) throws IOException, InterruptedException {Configuration conf = job.getConfiguration();boolean isCompressed = getCompressOutput(job);String keyValueSeparator= conf.get(SEPERATOR, "\t");CompressionCodec codec = null;String extension = "";if (isCompressed) {Class<? extends CompressionCodec> codecClass = getOutputCompressorClass(job, GzipCodec.class);codec = (CompressionCodec) ReflectionUtils.newInstance(codecClass, conf);extension = codec.getDefaultExtension();}Path file = getDefaultWorkFile(job, extension);FileSystem fs = file.getFileSystem(conf);if (!isCompressed) {FSDataOutputStream fileOut = fs.create(file, false);return new LineRecordWriter<K, V>(fileOut, keyValueSeparator);} else {FSDataOutputStream fileOut = fs.create(file, false);return new LineRecordWriter<K, V>(new DataOutputStream(codec.createOutputStream(fileOut)),keyValueSeparator);}}
}
  默认的情况下MR主程序中,设定输出编码的设置语句为:
job.setOutputFormatClass(TextOutputFormat.class);

上述代码的第48行可以看出hadoop已经限定此输出格式统一为UTF-8,因此为了改变hadoop的输出代码的文本编码只需定义一个和TextOutputFormat相同的类GbkOutputFormat同样继承FileOutputFormat
(注意是
org.apache.hadoop.mapreduce.lib.output.FileOutputFormat)
即可,如下代码

package com.ljt.hdfs;import java.io.DataOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.compress.CompressionCodec;
import org.apache.hadoop.io.compress.GzipCodec;
import org.apache.hadoop.mapreduce.RecordWriter;
import org.apache.hadoop.mapreduce.TaskAttemptContext;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.ReflectionUtils;
/*** * <p>* Title: GbkOutputFormat* </p>* <p>* 功能描述::* hadoop已经限定此输出格式统一为UTF-8,因此为了改变hadoop的输出代码的文本编码只需定义一个和TextOutputFormat相同的类GbkOutputFormat同样继承FileOutputFormat* (注意是 org.apache.hadoop.mapreduce.lib.output.FileOutputFormat)* </p>* <p>* Company: adteach* </p>* * @author 刘建涛 ** @date 2017年7月19日下午4:42:05* @version 1.0*/
@InterfaceAudience.Public
@InterfaceStability.Stable
public class GbkOutputFormat<K, V> extends FileOutputFormat<K, V> {public static String SEPERATOR = "mapreduce.output.textoutputformat.separator";protected static class LineRecordWriter<K, V>extends RecordWriter<K, V> {private static final String utf8 = "GBK";private static final byte[] newline;static {try {newline = "\n".getBytes(utf8);} catch (UnsupportedEncodingException uee) {throw new IllegalArgumentException("can't find " + utf8 + " encoding");}}protected DataOutputStream out;private final byte[] keyValueSeparator;public LineRecordWriter(DataOutputStream out, String keyValueSeparator) {this.out = out;try {this.keyValueSeparator = keyValueSeparator.getBytes(utf8);} catch (UnsupportedEncodingException uee) {throw new IllegalArgumentException("can't find " + utf8 + " encoding");}}public LineRecordWriter(DataOutputStream out) {this(out, "\t");}/*** Write the object to the byte stream, handling Text as a special* case.* @param o the object to print* @throws IOException if the write throws, we pass it on*/private void writeObject(Object o) throws IOException {if (o instanceof Text) {
//        Text to = (Text) o;
//        out.write(to.getBytes(), 0, to.getLength());
//      } else {out.write(o.toString().getBytes(utf8));}}public synchronized void write(K key, V value)throws IOException {boolean nullKey = key == null || key instanceof NullWritable;boolean nullValue = value == null || value instanceof NullWritable;if (nullKey && nullValue) {return;}if (!nullKey) {writeObject(key);}if (!(nullKey || nullValue)) {out.write(keyValueSeparator);}if (!nullValue) {writeObject(value);}out.write(newline);}public synchronized void close(TaskAttemptContext context) throws IOException {out.close();}}public RecordWriter<K, V> getRecordWriter(TaskAttemptContext job) throws IOException, InterruptedException {Configuration conf = job.getConfiguration();boolean isCompressed = getCompressOutput(job);String keyValueSeparator= conf.get(SEPERATOR, "\t");CompressionCodec codec = null;String extension = "";if (isCompressed) {Class<? extends CompressionCodec> codecClass = getOutputCompressorClass(job, GzipCodec.class);codec = (CompressionCodec) ReflectionUtils.newInstance(codecClass, conf);extension = codec.getDefaultExtension();}Path file = getDefaultWorkFile(job, extension);FileSystem fs = file.getFileSystem(conf);if (!isCompressed) {FSDataOutputStream fileOut = fs.create(file, false);return new LineRecordWriter<K, V>(fileOut, keyValueSeparator);} else {FSDataOutputStream fileOut = fs.create(file, false);return new LineRecordWriter<K, V>(new DataOutputStream(codec.createOutputStream(fileOut)),keyValueSeparator);}}
}

最后将输出编码类型设置成GbkOutputFormat.class,如:
job.setOutputFormatClass(GbkOutputFormat.class);

hadoop MapReduce 输出结果中文乱码解决相关推荐

  1. 成功解决连接SQL输出出现中文乱码问题(10001, 'oracle¿ìËÙÈëÃÅ', 'Íõº£ÁÁ', 'Ë®Àû³ö°æÉç',

    成功解决连接SQL输出出现中文乱码问题(10001, 'oracle¿ìËÙÈëÃÅ', 'Íõº£ÁÁ', 'Ë®Àû³ö°æÉç', 目录 解决问题 解决思路 解决方法 解决问题 解决连接SQL出 ...

  2. python2中文输出代码_解决vscode python print 输出窗口中文乱码的问题

    解决vscode python print 输出窗口中文乱码的问题 发布时间:2020-09-17 23:53:25 来源:脚本之家 阅读:119 一.搭建 python 环境 在 VSC 中点击 F ...

  3. QT5 界面截图保存到本地+输出PDF/WORD格式文档+QT界面中文乱码及输出PDF中文乱码的解决(亲身实践并且成功)

    最近做了一个和QT5有关的项目,遇到很多问题也学习到不少,特意写下来希望帮到更多的人.(我的版本VS2017+QT5.12.0) 一.QT5截图并保存到本地 在头文件添加必须项 #include &l ...

  4. Spark读取日志文件集中文乱码解决方法

    Spark读取日志中文乱码解决方法 问题展示 ���� 一般来说,这个问题多出现于GBK与UTF-8编码互相转换时.众所周知,GBK编码是windows系统的编码格式,而UTF-8是linux系统的编 ...

  5. vs code中文乱码解决方法

    修改 1.(安装方法) 2.显示终端输入数据输出结果(完美解决) 3.修改部分:中文乱码解决方法 第一步: 第二步: 1.(安装方法) 转载于: https:blog.csdn.net/qq_4304 ...

  6. 在一个JS文件中包含中文字符串,通过innerHTML输出后中文乱码?

    在一个JS文件中包含中文字符串,通过innerHTML输出后中文乱码? Posted on 2008-07-13 12:00 尹合磊 阅读(1902) 评论(0)  编辑 收藏 所属分类: ASP.N ...

  7. Java中文jsp页面_java中文乱码解决之道(七)—–JSP页面编码过程

    我们知道JSP页面是需要转换为servlet的,在转换过程中肯定是要进行编码的.在JSP转换为servlet过程中下面一段代码起到至关重要的作用. 在上面代码中有两个地方存在编码:pageEncodi ...

  8. java 页面编码_java中文乱码解决之道(七)-----JSP页面编码过程

    我们知道JSP页面是需要转换为servlet的,在转换过程中肯定是要进行编码的.在JSP转换为servlet过程中下面一段代码起到至关重要的作用. 在上面代码中有两个地方存在编码:pageEncodi ...

  9. eclipse java web乱码,eclipse中文乱码解决

    本文收集整理关于eclipse中文乱码解决的相关议题,使用内容导航快速到达. 内容导航: Q1:eclipse中java中文控制台输出的这种乱码怎么解决 eclipse中java中文控制台输出的这种乱 ...

  10. X64dbg 2021最新版 中文乱码解决

    X64dbg中文乱码解决 X64dbg可以对64位的软件进行反编译,是针对Olldbg只能调试32位软件的改进,使用也比较方便.但由于该软件前端使用QT开发,对中文的解析经常会出现乱码,不能很好解析出 ...

最新文章

  1. flex swf和movieclip之前的微妙关系
  2. 在单链表和双链表中删除倒数第K个节点
  3. 001 GIt的基本操作
  4. [JavaWeb-JavaScript]JavaScript流程控制语句
  5. shell 删除了hdfs 文件,在HDFS上删除超过10天的文件
  6. synchronized可重入锁
  7. [Windows Server 2008] 404错误设置方法
  8. 关于macOS自定义终端命令的方法
  9. ldo和dcdc功耗_LDO和DCDC电源的优缺点以及差别
  10. 网络工程师考试知识点[必考知识点]--必看
  11. 丧心病狂的外挂:透视穿墙,带老板坐飞机,打不过就炸房
  12. CS5213 HDMI转VGA带音频DAC输出|HDMI to VGA withDAC转换
  13. 知识工程重点知识介绍-1
  14. 普通路由器改4g路由器_4G工业路由器物联卡批发价格是多少?良心厂家推荐
  15. 一次聚类引发的一系列问题(多线程篇-多线程慢于单线程)
  16. 《纽约客》特写Jeff Dean与Sanjay:谷歌唯二11级工程师,同一台电脑上写代码
  17. 拼多多商品发布规则|一度智信
  18. 3D视觉检测风挡玻璃智能涂胶工作站
  19. 数学建模——评价算法
  20. Flutter 保护你的APP数据安全

热门文章

  1. 回顾 | Apache Flink x TiDB Meetup · 北京站(附 PPT 下载)
  2. ijkplayer中遇到的问题汇总
  3. 非科班普通本科就注定进不了大厂?我不服
  4. python---用python实现选择排序
  5. python的变量在使用前不需要先赋值_每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建。_学小易找答案...
  6. 乌班图服务器应用,Ubuntu下安装Apache
  7. java kaptcha_kaptcha Java验证码
  8. ping,python实现批量ping包工具--小案例v4优化版本
  9. android 原理 组合控件_Android自定义控件之组合控件
  10. 基于Yolov5目标检测的物体分类识别及定位(二) -- yolov5运行环境搭建及label格式转换