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

升级HBase2字符编码问题以及中文显示,第1张

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

文章目录
  • (一)问题
  • (二)分析
    • 2.1 读文件字符集正确
    • 2.2 Hbase中也是GBK?
    • 2.3 放入Hbase时String与byte[]转换问题?
  • (三)解决

(一)问题

把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=xE7xABxA0xE6x8BxA8xE7x8Ex89
 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"));

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5696251.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存