Hadoop0.20.2中MapReduce读取gb2312文件出现乱码问题

单位用的是Linux系统的字符编码是gb2312,所以生成的文件都是按照默认编码生成的。给我的文件也都是gb2312的,在hadoop中运行mapreduce出现乱码,在网上查资料说是因为hadoop的文件系统默认用的是utf-8,那么只有两条路可以选,要么改文件的编码格式,要么改在Mapreduce程序中想办法转一下。很显然改文件的编码格式是不现实的,因为客户那边用C++生成的文件千千万万,而且原来的老程序还在不断的生成,要他们改程序涉及到的工作量太大了。所以这能我这边想办法了。

因为Mapreduce涉及到读和写两个操作。首先在Map中读的时候需要使用gb2312的方式去读取文件,然后Reduce中写文件的时候需要以gb2312的方式去写。想想其实如果在Reduce中写的时候不用gb2312的方式去写,那么就用默认的UTF-8去写,原理上只要把这个文件下载下来,拷贝到一个能够识别gb2312文件格式的系统上去,应该看到的不是乱码,这个没有试过。由于操作系统字符编码是gb2312,所以为了生成的文件不是乱码,reduce中写的是时候还是用gb2312的方式去写吧。下面说说具体操作步骤:

1、在Map中以gb2312的方式去读取文件,只需要两行代码转换一下就可以。

String line = value.toString();
line = new String(line .getBytes(), 0, line .length, "gb2312");

2、在reduce中写的时候用gb2312去写,这个时候需要重写一个类,代替原来的TextOutputFormat类。新的类代码如下:

 public class GbkOutputFormat<K, V> extends FileOutputFormat<K, V> {
  protected static class LineRecordWriter<K, V>
    implements RecordWriter<K, V> {
    //写成gbk即可
    private static final String gbk = “gb2312”;
    private static final byte[] newline;
    static {
      try {
        newline = “\n”.getBytes(gbk);
      } catch (UnsupportedEncodingException uee) {
        throw new IllegalArgumentException(“can’t find ” + gbk + ” encoding”);
      }
    }
…
    public LineRecordWriter(DataOutputStream out, String keyValueSeparator) {
      this.out = out;
      try {
        this.keyValueSeparator = keyValueSeparator.getBytes(gbk);
      } catch (UnsupportedEncodingException uee) {
        throw new IllegalArgumentException(“can’t find ” + gbk + ” encoding”);
      }
    }
…
    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(gbk));
      }
    }
 …
}
    然后在mapreduce代码中加入conf1.setOutputFormat(GbkOutputFormat.class)
    即可以gbk格式输出中文。

本文参考:http://blog.csdn.net/zklth/article/details/11829563

时间: 2024-11-05 06:27:29

Hadoop0.20.2中MapReduce读取gb2312文件出现乱码问题的相关文章

关于读取txt文件中文乱码问题

在处理文件的过程中,读取txt文件出现中文乱码.这种情况是由于编码字符不一致导致. public static string ReadFile(string path, string fileName) { FileStream stream = null; StreamReader reader = null; StringBuilder v = new StringBuilder(); try { stream = new FileStream(path + fileName, FileMo

【 D3.js 进阶系列 — 1.2 】 读取 CSV 文件时乱码的解决方法

在 D3 中使用 d3.csv 读取 CSV 文件时,有时会出现乱码问题.怎么解决呢? 1. 乱码问题 使用 d3.csv 读取 xxx.csv 文件时,如果 xxx.csv 文件使用的是 UTF-8 编码,不会有什么问题.当然,个人认为尽量使用 UTF-8 编码,可以在同一编码内使用各国文字. 但是,如果 xxx.csv 文件使用的是 utf-8 编码,使用 Microsoft Excel 打开的时候,可能会出现乱码,因为国内的 Excel 默认使用 GB2312 打开,而且在打开的时候不能选

ASP中Utf-8与Gb2312编码转换乱码问题的解决方法 页面编码声明

1 ASP程序在同一个站点中,如果有UTF-8编码的程序,又有GB2312编码的程序时,在浏览UTF-8编码的页面后,再浏览当前网站GB2312的页面,GB2312编码的页面就会出现乱码 2 出现这样的问题是当你浏览UTF-8编码的时候,服务器默认用UTF-8的引擎来输出html,当你用再浏览GB2312的页面时,它还是用UTF-8来输出本应是GB2312编码的页面所以会乱码. 3 4 5 6 首先让我们来了解一下Session对象提供了四个属性. 7 1.CodePage 读/写.整型. 8

解決BufferedReader读取UTF-8文件中文乱码(转)

读取txt文件乱码 Java代码 BufferedReader read = new BufferedReader(new FileReader(new File(filename))); 解决办法: Java代码 InputStreamReader isr = new InputStreamReader(new FileInputStream(file), "UTF-8"); BufferedReader read = new BufferedReader(isr); 因为Input

Jmeter中随机读取测试文件的内容

性能测试中需要测试这么一个场景:测试数据是一堆的地址,存储在一个文件中.为了模仿真实的用户访问场景,需要从这个文件中每次随机选取地址,拼接在一个固定的域名后发送出去.看了半天jmeter的帮助文档,也在网上搜了半天,用jmeter的Groovy脚本解决: import java.text.*;import java.io.*;import java.util.*; String csvTest = "test_data.csv";//csvDir = vars.get("fi

tomcat中如何读取properties文件

最近正在努力学习中...我会把我每天学到的知识上传到我的博客中,希望和大家交流,勿喷>. 首先要明白普通java项目跟服务器中的路径是不同的,普通java项目寻找路径直接写绝对路径就可以,但是服务器上的路径不能直接写你的eclips中的路径. 当你的servlet类编译以后,它会编译到你的tomcat文件夹下的webapps/projectName/WEB-INF/classes文件夹中. 可以使用ServletContext对象的getReSourceAsStream()方法获取一个文件输入流

Eclipse 中读取properties文件中文乱码解决问题

在开发java中多少会遇到需要编辑properties等属性文件的时候,有时候用文本编辑器看到的内容会使各种的乱码入下图: 针对这种情况可以给Eclipse安装上一个插件Properties Editor,属性文件通过这个编辑器打开可以解决乱码问题. 安装插件方法:help--Eclipse Marketplace如下图,我的Eclipse是Mars Release (4.5.0)

Matlab中如何读取.dat文件

处理movielens1M数据集 中间有个双冒号,直接用load的只读取第一列,这时候我们可以用dlmread(中间是l不是i),如下图,只需要提取1 3 5列就好了.

【转】MapReduce读取lzo文件

1.读lzo文件 需要添加以下代码,并导入lzo相关的jar包 job.setInputFormatClass(LzoTextInputFormat.class); 2.写lzo文件 lzo格式默认是不支持splitable的,需要为其添加索引文件,才能支持多个map并行对lzo文件进行处理 如果希望reduce输出的是lzo格式的文件,添加下面的语句        FileOutputFormat.setCompressOutput(job, true);        FileOutputF