• Mapper输出数据中文乱码


    在做Map Join案例实操的时候,发现处理后的结果数据居然中文乱码。

    大致需求是这样的:有两张表希望输出最终数据格式。
    在这里插入图片描述
    在这里插入图片描述
    我们采用MapJoin的方式实现,将较小的表pd表加载到缓存中,保存到map集合中,然后Mapper中的map方法处理order表,将pid替换为pname

    Mapper类

    package com.qcln.mr.mapjoin;
    
    import org.apache.commons.lang.StringUtils;
    import org.apache.hadoop.fs.FSDataInputStream;
    import org.apache.hadoop.fs.FileSystem;
    import org.apache.hadoop.fs.Path;
    import org.apache.hadoop.io.IOUtils;
    import org.apache.hadoop.io.LongWritable;
    import org.apache.hadoop.io.NullWritable;
    import org.apache.hadoop.io.Text;
    import org.apache.hadoop.mapreduce.Mapper;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.net.URI;
    import java.util.HashMap;
    import java.util.Map;
    
    public class MJMapper extends Mapper<LongWritable, Text,Text, NullWritable> {
    
        private Map<String,String> pMap = new HashMap<>();
        private Text k = new Text();
    
        @Override
        protected void setup(Context context) throws IOException {
            //读取pd到pMap
            //开流
            URI[] cacheFiles = context.getCacheFiles();
            FileSystem fs = FileSystem.get(context.getConfiguration());
            FSDataInputStream open = fs.open(new Path(cacheFiles[0]));
    
            //将文件按行处理,读取到pMap中
            // 因为上面的字节流没法读一行,所以要转换流,转换成字符流
            BufferedReader br = new BufferedReader(new InputStreamReader(open));
            String line;
            while(StringUtils.isNotEmpty(line = br.readLine())){
                String[] split = line.split("\t");
                pMap.put(split[0],split[1]);
            }
    
            IOUtils.closeStream(br);
        }
    
        /**
         * 处理order.txt文件
         * @param key
         * @param value
         * @param context
         * @throws IOException
         * @throws InterruptedException
         */
        @Override
        protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
    
            String[] fields = value.toString().split("\t");
            // 将pid替换
            k.set(fields[0] + "\t" + pMap.get(fields[1])+ "\t" + fields[2]);
    
            context.write(k,NullWritable.get());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62

    Driver类

    package com.qcln.mr.mapjoin;
    
    import org.apache.hadoop.conf.Configuration;
    import org.apache.hadoop.fs.Path;
    import org.apache.hadoop.io.NullWritable;
    import org.apache.hadoop.io.Text;
    import org.apache.hadoop.mapreduce.Job;
    import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
    import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
    
    import java.io.IOException;
    import java.net.URI;
    
    public class MJDriver {
        public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
            Job job = Job.getInstance(new Configuration());
    
            job.setJarByClass(MJDriver.class);
    
            job.setMapperClass(MJMapper.class);
            job.setNumReduceTasks(0);
    
            //添加分布式缓存
            job.addCacheFile(URI.create(args[0]));
    
            job.setMapOutputKeyClass(Text.class);
            job.setMapOutputValueClass(NullWritable.class);
    
            FileInputFormat.setInputPaths(job,new Path(args[1]));
            FileOutputFormat.setOutputPath(job,new Path(args[2]));
    
            boolean b = job.waitForCompletion(true);
            System.exit(b ? 0 : 1);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    然而运行结果是:
    请添加图片描述

    这显然不对,怎么会有乱码呢?按道理输出应该是这样子的啊。

    请添加图片描述
    我明明输入文件都是UTF-8的,为啥处理后就乱码了呢。再去检查代码,发现在流转换操作的时候加上字符编码就不会产生乱码,将代码改成如下

    BufferedReader br = new BufferedReader(new InputStreamReader(open,"UTF-8"));
    
    • 1

    再次测试,乱码问题解决。

    所以以后在进行流转换操作的时候要格外留意一下字符编码问题,很容易漏掉

  • 相关阅读:
    【Pyqt5】windows和linux安装Pyqt5+designer
    mysql-面试50题-4
    平均风向风速计算(单位矢量法)
    Typescript高级: 深入理解extends keyof语法
    2、RocketMQ消息的分类
    直播软件App开发趋势:2023年最值得关注的五大技术突破
    【快应用】微信H5 referer支付未拉起微信收银台
    A-Level化学例题解析及练习Isomers
    WebRTC源码之摄像头视频数据采集源码分析
    多线程(虚拟地址空间)
  • 原文地址:https://blog.csdn.net/qq_45796486/article/details/126131205