从文件执行配置单元时查询编码不正确

g52tjvyc  于 2021-06-02  发布在  Hadoop
关注(0)|答案(1)|浏览(326)

我有一个包含cjk字符的配置单元查询,文件如下:

SELECT * FROM tbl WHERE name LIKE '日本語%';

文件以utf-8编码:

> file -bi query.hql
text/plain; charset=utf-8

如果我用hive cli执行它,我可以得到预期的结果:

> /path/to/hive -f query.hql
some results here

现在我想从java执行这个查询。所以我写了一些代码,比如:

String[] cmd = new String[]{"/bin/bash", "/my/script", "/path/to/query.hql", "/path/to/output.txt"};
ProcessBuilder pb = new ProcessBuilder(cmd);
...
pb.start();
...

以及 /my/script 看起来像:

HQL_FILE=$1
OUTPUT_FILE=$2
/path/to/hive -f "${HQL_FILE}" > "${OUTPUT_FILE}"

我运行了java程序,但没有得到任何输出。我检查了配置单元日志文件,它看起来像是一个编码问题。
如果我跑了 hive -f query.hql 通过shell,cjk文本正确地记录在配置单元日志中:

> cat /tmp/myuser/hive.log
2016-02-29 11:27:40,303 INFO  [main]: parse.ParseDriver (ParseDriver.java:parse(185)) - Parsing command: ... name LIKE '日本語%' ...

但是如果我通过上面的java程序运行,日志看起来很奇怪

> cat /tmp/myuser/hive.log
2016-02-29 11:29:41,104 INFO  [main]: parse.ParseDriver (ParseDriver.java:parse(185)) - Parsing command: ... name LIKE '???????%' ...

我已经调查这个问题半天了,但找不到任何有用的信息。
如果有人能给我一些建议,我将不胜感激。
附言:
配置单元服务器不是一个选项。我必须通过shell调用配置单元客户端。
我用的是Hive0.14.0。

8wigbo56

8wigbo561#

假设java程序本身没有编写hql文件,在hive命令工作的shell中,运行以下命令:

echo $LANG

你可能会得到 en_US.UTF-8 .
在创建processbuilder之后,获取您获得的任何值并修改java程序以获得该值:

pb.environment().put("LANG", "en_US.UTF-8");

(使用你得到的任何值,而不是en\u us.utf-8)
如果您的java程序正在编写hql文件本身,那么还有其他一些问题需要担心:当您打开文件时,应该为输出指定utf-8编码。如何做到这一点将取决于你如何打开文件位。

相关问题