python3上的paramiko底层的代码将解析的编码设置成utf-8,并且没有提供接口修改编码,导致通过paramiko远程连接服务器时,当编码不是utf-8时,很容易出现编码出错的问题;以下是具体的问题和解决方案:
案例:公司要到sfg服务器上查询文件,但是paramiko底层设置的编码是UTF-8,但是公司的sfg服务器用的其他编码,如GB2312,导致paramiko采用listdir时,查询文件存在中文时,有的编码采用utf-8无法解析,导致报错;
解决方案:
修改底层代码,主要是sftp_client.py的文件和message.py文件;
(1)复制sftp_client.py文件,修改为sftp_client_up.py,对sftp_client_up.py中的SFTPClient类进行修改;
(2)复制message.py文件,修改为message.py,对.py中的Message类进行修改;
具体修改的地方有以下几点:
sftp_client_up.py文件
(a)之前sftp_client.py文件导入的是message.py这个文件中的Message类,现在改成导入message_up.py这个文件中的Message类
#from paramiko.message import Message
from message_up import Message
(2)对message_up.py文件中的Message类进行修改,修改get_text()方法
class Message(object):
def get_text(self):
"""
Fetch a Unicode string from the stream.
"""
return u(self.get_string(),encoding=‘GB2312’)
原理:
(1)我们之前在创建paramiko连接后,会调用sftp_client.py中的SFTPClient类,并用到了该类中的listdir()方法,该方法会创建Message类,改类中会去上游的sfg服务器上查询出结果,并按照二进制的形式传输过来,之后会对二进制的字符串进行解码,解码的字符设置成utf-8;
(2)我们这边修改了调用的SFTPClient类,用了我们自己的类,改类又会调用Message类,Message类也是我们自己的类,并修改了解析二进制字符串的编码格式,设置成GB2312