java 将从读取到的外部调用程序的带有日文字符的输出信息 输出到Jenkins 上的Console Output 上乱码。
现象分析:
Jenkins 上可以将日文正常显示出来,但是读取外部程序的输出信息的日文却不能正常显示。
Java Console 输出 | Jenkins Console Output 输出调用程序的输出信息 | Jenkins Consloe Oputput 输出非调用程序的输出信息 |
正常 | 不正常 | 正常 |
更改了自己机器和日本机器Eclipse里的各种encoding的设置,改成UTF-8也是没有任何用处。
原因解释
所以问题的关键还是在于读取外部程序输出信息的代码上。
从网上看了好多关于Java编码的问题,最后找到问题的根源在于InputStreamReader 的编码问题。
InputStreamReader是字节流通向字符流的桥梁,封裝了InputStream在里头, 它以较高级的方式,一次读取一个一个字符,以文本格式输入 / 输出,可以指定编码格式;
它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。
每次调用 InputStreamReader 中的一个 read() 方法都会导致从底层输入流读取一个或多个字节。要启用从字节到字符的有效转换,可以提前从底层流读取更多的字节,使其超过满足当前读取操作所需的字节。 为了达到最高效率,可要考虑在 BufferedReader 内包装 InputStreamReader。例如:
BufferedReader
in = new BufferedReader(new InputStreamReader(System.in));
BufferedReader 由Reader类扩展而来,提供通用的缓冲方式文本读取,而且提供了很实用的readLine,读取一个文本行,从字符输入流中读取文本,缓冲各个字符,从而提供字符、数组和行的高效读取。BufferedReader的最大特点就是缓冲区的设置。通常Reader 所作的每个读取请求都会导致对底层字符或字节流进行相应的读取请求,如果没有缓冲,则每次调用
read() 或 readLine() 都会导致从文件中读取字节,并将其转换为字符后返回,而这是极其低效的。
InputStreamReader最大的特点是可以指转换的定编码格式,这是其他类所不能的,从构造方法就可看出,一点在读取中文字符时非常有用。
知道了问题所在,就可以改代码了
代码
try {
BufferedReader br1 = new BufferedReader(new InputStreamReader(br,"UTF-8"));
String line1 = null;
while ((line1 = br1.readLine()) != null) {
if (line1 != null){
logger.info("info: "+line1);
}
}
} catch (IOException e) {
e.printStackTrace();
}