zoukankan      html  css  js  c++  java
  • 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 = “
    ”.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

  • 相关阅读:
    今发现“最全前端资源汇集”,果断收藏
    js基础
    重排版与重绘
    小乌龟的配置
    考试网站
    苹果手机上时间的兼容
    自定义alert
    [概率dp] 流浪地球
    [权值线段树] 1163B2 Cat Party (Hard Edition)
    [单调栈]1156E Special Segments of Permutation
  • 原文地址:https://www.cnblogs.com/gaojiang/p/4829240.html
Copyright © 2011-2022 走看看