Java读取Hdfs的文件数据出现乱码的解决方案和办法

使用JAVA api读取HDFS文件乱码踩坑

想写一个读取HFDS上的部分文件数据做预览的接口,根据网上的博客实现后,发现有时读取信息会出现乱码,例如读取一个csv时,字符串之间被逗号分割

英文字符串aaa,能正常显示
中文字符串“你好”,能正常显示
中英混合字符串如“aaa你好”,出现乱码
查阅了众多博客,解决方案大概都是:使用xxx字符集解码。抱着不信的想法,我依次尝试,果然没用。

解决思路

因为HDFS支持6种字符集编码,每个本地文件编码方式又是极可能不一样的,我们上传本地文件的时候其实就是把文件编码成字节流上传到文件系统存储。那么在GET文件数据时,面对不同文件、不同字符集编码的字节流,肯定不是一种固定字符集解码就能正确解码的吧。

那么解决方案其实有两种

固定HDFS的编解码字符集。比如我选用UTF-8,那么在上传文件时统一编码,即把不同文件的字节流都转化为UTF-8编码再进行存储。这样的话在获取文件数据的时候,采用UTF-8字符集解码就没什么问题了。但这样做的话仍然会在转码部分存在诸多问题,且不好实现。
动态解码。根据文件的编码字符集选用对应的字符集对解码,这样的话并不会对文件的原生字符流进行改动,基本不会乱码。
我选用动态解码的思路后,其难点在于如何判断使用哪种字符集解码。参考下面的内容,获得了解决方案

java检测文本(字节流)的编码方式

需求:

某文件或者某字节流要检测他的编码格式。

实现:

基于jchardet

1
2
3
4
5

net.sourceforge.jchardet
jchardet
1.0

代码如下:

public class DetectorUtils {
   
    private DetectorUtils() {
   
    }
  
    static class ChineseCharsetDetectionObserver implements
            nsICharsetDetectionObserver {
   
        private boolean found = false;
        private String result;
  
        public void Notify(String charset) {
   
            found = true;
            result = charset;
        }
  
        public ChineseCharsetDetectionObserver(boolean found, String result) {
   
            super();
            this.found = found;
            this.result = result;
        }
  
        public boolean isFound() {
   
            return found;
        }
  
        public String getResult() {
   
            return result;
        }
  
    }
  
    public static String[] detectChineseCharset(InputStream in)
            throws Exception {
   
        String[] prob=null;
        BufferedInputStream imp = null;
        try {
   
            boolean found = false;
            String result = Charsets.UTF_8.toString();
            int lang = nsPSMDetector.CHINESE;
            nsDetector det = new nsDetector(lang)
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值