- (一)问题
- (二)分析
- 2.1 读文件字符集正确
- 2.2 Hbase中也是GBK?
- 2.3 放入Hbase时String与byte[]转换问题?
- (三)解决
把Hbase1.x升级到2.X后,用程序从文本导入数据,查询时中文会变成乱码。
程序一行都没有改过,Hbase1正常而2乱码???
隐约感觉似乎又是错过了什么。
数据是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么?
继续检查代码,既然从文件读出来没有问题,那么下一步是放入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的编码就不能确定了。
难道是:
- 升级Hbase2后用Windows平台导入了文件,而Hbase1时都用的Linux导入?
- 升级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"));
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)