由于Hadoop默认编码为UTF-8,并且将UTF-8进行了硬编码,所以我们在处理中文时需要重写OutputFormat类。方法为:
1、新建类GBKFileOutputFormat,代码如下:
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.mapreduce.lib.*;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
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.OutputFormat;
import org.apache.hadoop.mapreduce.RecordWriter;
import org.apache.hadoop.mapreduce.TaskAttemptContext;
import org.apache.hadoop.util.*;
/** An {@link OutputFormat} that writes plain text files. */
public class GBKFileOutputFormat<K, V> extends FileOutputFormat<K, V> {//TextInputFormat是默认的输出文件格式
protected static class LineRecordWriter<K, V>//默认
extends RecordWriter<K, V> {
private static final String utf8 = "GBK"; //硬编码,将“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;//key和value的分隔符,默认的好像是Tab
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输出流是byte格式的
* case.
* @param o the object to print是要输出的对象
* @throws IOException if the write throws, we pass it on
*/
private void writeObject(Object o) throws IOException {//应该是一行一行的写 key keyValueSeparator value \n
if (o instanceof Text) {//如果o是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 {
//下面是为了判断key和value是否为空值
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//获得writer实例
) throws IOException, InterruptedException {
Configuration conf = job.getConfiguration();
boolean isCompressed = getCompressOutput(job);//
String keyValueSeparator= conf.get("mapred.textoutputformat.separator",
"\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);//这个是获取缺省的文件路径及名称,在FileOutput中有对其的实现
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);
}
}
}
该类是在源代码中TextOutputFormat类基础上进行修改的,在这需要注意的一点是继承的父类FileOutputFormat是位于org.apache.hadoop.mapreduce.lib.output包中的
2、在主类中添加job.setOutputFormatClass(GBKFileOutputFormat.class);
相关推荐
【Hadoop中文乱码问题详解】 在大数据处理领域,Hadoop是一个不可或缺的开源框架,它提供了分布式存储(HDFS)和分布式计算(MapReduce...通过本文的讲解,希望能帮助你有效解决Hadoop处理中文数据时遇到的乱码难题。
- **社交网络**:社交媒体平台利用Hadoop处理用户生成的内容,如帖子、评论和图片等。 - **科学研究**:科学家们可以使用Hadoop来处理和分析天文观测数据、基因组序列数据等。 - **金融领域**:金融机构使用Hadoop...
这些工具和服务共同构成了一个完整的解决方案,用于处理各种类型的大数据问题。 #### Hive Hive是一种数据仓库工具,可以将结构化数据文件映射为表,并提供简单的SQL查询功能。通过Hive,用户可以轻松地对Hadoop...
Hadoop API中文说明文档是针对Apache Hadoop框架的开发者指南,它详细解释了如何使用...通过深入阅读和理解Hadoop API中文说明文档,开发者可以更好地利用Hadoop平台解决大数据问题,实现高效、可靠的分布式计算。
Hadoop作为一个成熟的分布式系统基础设施,已经成为大数据处理的标准解决方案之一,尤其在处理大量数据的场合被广泛应用。本书由清华大学出版社出版,是全面系统学习Hadoop各个组件和功能的优秀教材。 Hadoop的核心...
Hadoop是Apache软件基金会开发的一个开源分布式计算框架,主要用于处理和存储海量数据。...通过深入学习和实践,你将能够熟练掌握如何利用Hadoop处理和分析大规模数据,为企业或项目带来数据驱动的洞察力。
通过阅读这份“Hadoop官方文档中文版”,开发者和管理员可以深入了解Hadoop的工作原理、配置方法、最佳实践以及如何解决常见问题,从而更好地利用Hadoop处理大数据挑战。这份文档对于学习和掌握Hadoop技术至关重要,...
6. 实际案例分析:基于真实业务场景的问题解决方案。 通过上述提供的学习资料和资源,可以系统地学习Hadoop的相关知识,并通过实际的视频教程和书籍来加深理解和实际应用能力。加微信***可以获取这些学习资料和视频...
7. 故障排查和监控:提供解决常见问题的方法,以及如何使用Hadoop自带的监控工具。 通过深入学习和实践Hadoop中文版API,开发者能够更有效地开发和优化大数据处理程序,充分利用Hadoop平台的潜力,处理海量数据并...
6. 实际应用案例和解决方案。 7. 高级主题,如性能优化、故障恢复和安全性。 总之,《Hadoop权威指南》中文版为读者提供了全面且深入的Hadoop学习资源,无论你是初学者还是经验丰富的开发者,都能从中获益良多,...
这些项目协同工作,提供了从数据存储、查询、分析到管理的全方位解决方案。 四、Hadoop安装与配置 安装Hadoop涉及多个步骤,包括环境准备、配置文件修改、集群部署等。书中会详细介绍如何在单机模式、伪分布式模式...
《数据算法:Hadoop/Spark大数据处理技巧》介绍了很多基本设计模式、优化技术和数据挖掘及机器学习解决方案,以解决生物信息学、基因组学、统计和社交网络分析等领域的很多问题。这还概要介绍了MapReduce、Hadoop和...
8. 实战应用:通过实例分析,展示Hadoop在实际业务场景中的解决方案。 总的来说,《Hadoop权威指南(第四版)》是一本全方位、深度解析Hadoop技术的宝典,无论是初学者还是资深开发者,都能从中受益匪浅。配合源...
《Hadoop中文实战》是一本面向初学者的指南,旨在帮助读者快速掌握Hadoop的核心概念和技术,从而在大数据处理领域奠定坚实的基础。Hadoop作为开源的分布式计算框架,已经成为处理海量数据的关键工具,广泛应用于...
在实时数据分析领域,ELK(Elasticsearch、Logstash、Kibana)栈提供了从数据采集、处理到可视化的完整解决方案。 - **节点个数考量**:节点个数不是越多越好,应根据具体需求和数据特性来确定。对于数据量不大且...
《Hadoop权威指南》作为一本深入浅出介绍Hadoop技术的书籍,不仅涵盖了Hadoop的基本概念和技术细节,还提供了丰富的实践案例和解决方案。无论是对于Hadoop初学者还是有一定经验的技术人员来说,这本书都是一个宝贵的...
YARN的引入解决了早期版本的资源管理问题,提高了集群效率。 7. **Hadoop的安全性**:Hadoop支持多种安全机制,如Kerberos认证、ACLs(访问控制列表)和加密,以保护数据的安全。 8. **Hadoop的实际应用**:Hadoop...
在大数据时代,Hadoop已经成为了企业级大数据解决方案的基石。《Hadoop权威指南》第四版中文版不仅适合初学者入门,也对有经验的Hadoop用户提供了深入的技术指导。通过学习本书,读者能够掌握Hadoop的核心原理,提升...