网上现有的无法正确解决的方法
如下:
- data.encode(‘utf-8’, errors=‘ignore’).decode(‘utf-8’)。(使用python中的编码和解码)
- 在头部加上# encoding:utf-8等方式
- 修改python文件的编码格式(在setting里面设置file Ecoding编码)修改java的虚拟机输出参数
- 使用new String(result.getBytes(“iso8859-1”),“utf-8”)转换等
一、乱码原因分析
通常出现乱码情况的时候,我们第一反应是文件编码设置是不是一样的,但这里通过Java调用python代码执行时,所有编码格式都是“UTF-8”,所以不存在这样的问题。
而之所以乱码,是因为python的print函数机制问题。
我们通过执行如下python代码,可以输出print函数输出的默认编码格式。
Python代码
1 2 | import locale print (locale.getdefaultlocale()) |
代码执行结果
(‘zh_CN’, ‘cp936’)
通过查阅我们可以知道“cp936”代表的是GB2312,即为中文编码。
二、正确解决方案
测试可用的方法有两种,一种在Java代码设置,另一种在Python代码中设置。
2.1 方法1——在Java代码中设置编码格式
这里使用Process和Runtime调用python代码,然后将获取到的输入流编码设置为”gb2312″
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | try { String result = ""; / / 这个方法是类似隐形开启了命令执行器,输入指令执行python脚本 String exe = "python解释器所处的绝对路径" ; String py = "python代码文件绝对地址" ; Process process = Runtime.getRuntime(). exec (exe + " " + py); / / 这种方式获取返回值的方式是需要用python打印输出,然后java去获取命令行的输出,在java返回 / / 获取结果的同时设置输入流编码格式 "gb2312" InputStreamReader isr = new InputStreamReader(process.getInputStream(), "gb2312" ); LineNumberReader input = new LineNumberReader(isr); result = input .readLine(); input .close(); isr.close(); int re = process.waitFor(); System.out.println(result); } catch (InterruptedException | IOException e) { System.out.println( "调用python脚本并读取结果时出错:" + e.getMessage()); } |
注意: 不能读取完字节流再次使用getByte重新编码,否则将会得到另一种乱码输出。
错误代码如下:
1 2 3 4 5 6 7 | InputStreamReader isr = new InputStreamReader(process.getInputStream(), "gb2312" ); LineNumberReader input = new LineNumberReader(isr); result = input .readLine(); result1 = new String(result.getBytes( "iso8859-1" ), "utf-8" ); input .close(); isr.close(); System.out.println(result1); |
2.2 方法2——在Python代码中设置编码格式
当不确定在Java中会使用什么方式调用python代码时(如不使用Process),可以在python代码中直接设置编码格式。
设置代码如下:
1 2 3 | import sys import io sys.stdout = io.TextIOWrapper(sys.stdout. buffer , encoding = 'utf-8' ) |
总结
至此,乱码问题得到解决。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持IT俱乐部。