升级HBase2字符编码问题以及中文显示

(一)问题

把HBase1.x升级到2.X后,用程序从文本导入数据,查询时中文会变成乱码。
程序一行都没有改过,HBase1正常而2乱码???
隐约感觉似乎又是错过了什么。

(二)分析

2.1 读文件字符集正确

数据是GBK编码的文本,读取指定了字符集EncodingType=”GBK“:
这一步应该没有任何问题。

BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("./filename.txt"), Charset.forName(EncodingType))

2.2 HBase中也是GBK?

到HBase中查看:

hbase:006:0> get 'ZG_CRM','40000002XXXX',{FORMATTER=>'toString'}

发现查询结果中文显示的是类似于方块的乱码。
但查询各种资料得知,如果存入HBase的字节内容是UTF8的,就可以用toString显示中文。

找到一个很实用的快速检查乱码类型的对照表格:
看上去确实是GBK的字节内容被存进HBase了。

Java难道不是默认UTF8么?
在这里插入图片描述

2.3 放入HBase时String与byte[]转换问题?

继续检查代码,既然从文件读出来没有问题,那么下一步是放入HBase,代码大概如下:

Put put = new Put(CustID.getBytes());
put.addColumn("XXX".getBytes(), "YYY".getBytes(), CUSTNAME.getBytes());
...
puts.add(put);
...
table.put(puts);

其中String.getBytes()是这么描述的:
在这里插入图片描述
纳尼?platform‘s default charset!!!
如果不指定getBytes()的字符集,那么就是用操作系统的字符集,来取得这些字符串的字节码。呃,Windows是GBK,Linux是UTF8,那么存入HBase的编码就不能确定了。

难道是:

  1. 升级HBase2后用Windows平台导入了文件,而HBase1时都用的Linux导入?
  2. 升级HBase2后不保存编码信息,而HBase1保存(怎么可能)……

(三)解决

指定UTF-8字符集,取得字节码。

Put put = new Put(CustID.getBytes(StandardCharsets.UTF_8));
put.addColumn("XXX".getBytes(), "YYY".getBytes(), CUSTNAME.getBytes(StandardCharsets.UTF_8));
...
puts.add(put);
...
table.put(puts);

重新导入后,再HBASE中查看,可以正常toString显示中文了。

hbase:003:0> get 'ZG_CRM','40000002XXXX'
COLUMN                  CELL
 INFO:CUSTNAME          timestamp=2022-01-03T23:20:19.134, value=\xE7\xAB\xA0\xE6\x8B\xA8\xE7\x8E\x89
 REGION:REGIONCODE      timestamp=2022-01-03T23:20:19.134, value=792
 REGION:REGIONNBR       timestamp=2022-01-03T23:20:19.134, value=360423198201053227
1 row(s)
Took 0.0727 seconds
hbase:004:0>
hbase:006:0> get 'ZG_CRM','40000002XXXX',{FORMATTER=>'toString'}
COLUMN                  CELL
 INFO:CUSTNAME          timestamp=2022-01-03T23:20:19.134, value=章拨玉
 REGION:REGIONCODE      timestamp=2022-01-03T23:20:19.134, value=792
 REGION:REGIONNBR       timestamp=2022-01-03T23:20:19.134, value=360423198201053227
1 row(s)
Took 0.0062 seconds
hbase:007:0>

分别尝试从Linux和Windows入库同样的文件,均无乱码了:)


😄
PS:第一步读文本文件时,文本文件的编码(字符集)要指定正确。
否则后续就会错错错太不人道……

PS2:如果还在用如下的语句转换String的编码,那么说明前面已经读错了。

newStr = new String(oldStr.getBytes(oldCharset), newCharset);

or:

newStr = new String(new String(oldStr.getBytes(),"GBK").getBytes("UTF-8"));
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值