V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
ft3312591
V2EX  ›  Python

求教 sftp 库 paramiko 问题

  •  
  •   ft3312591 · 2019-08-19 10:56:11 +08:00 · 2777 次点击
    这是一个创建于 1905 天前的主题,其中的信息可能已经有所发展或是发生改变。
    需要通过 sftp 方式下载和上传文件,找到了 python 第三方 sftp 库 paramkio,但是发现对中文支持不好
    之前碰到一个中文名文件显示问题
    Traceback (most recent call last):
    File "<pyshell#0>", line 1, in <module>
    aa = sftp_test.listdir()
    File "C:\ProgramData\Anaconda3\lib\site-packages\paramiko\sftp_client.py", line 218, in listdir
    return [f.filename for f in self.listdir_attr(path)]
    File "C:\ProgramData\Anaconda3\lib\site-packages\paramiko\sftp_client.py", line 254, in listdir_attr
    filename = msg.get_text()
    File "C:\ProgramData\Anaconda3\lib\site-packages\paramiko\message.py", line 178, in get_text
    return u(self.get_string())
    File "C:\ProgramData\Anaconda3\lib\site-packages\paramiko\py3compat.py", line 156, in u
    return s.decode(encoding)
    UnicodeDecodeError: 'utf-8' codec can't decode byte 0xcd in position 0: invalid continuation byte
    网上找了下,发现原因是 paramkio 把编码写死了,全部都是 utf-8,
    https://www.cnblogs.com/kwang-cai/articles/10611946.html
    修改源码里的 py3compat.py 代码解决了,
    和网上不同的是,我改成 gb2312,而不是文中的 ISO-8859-1,(因为改成 ISO-8859-1 还是会有乱码,不知道为什么)
    然后碰到第二个问题,
    Traceback (most recent call last):
    File "<pyshell#4>", line 1, in <module>
    sftp_test.get('邮寄清单 20190816 日卡.zip', r'D:\App\ICcard_trans\邮寄清单 20190816 日卡.zip')
    File "C:\ProgramData\Anaconda3\lib\site-packages\paramiko\sftp_client.py", line 802, in get
    size = self.getfo(remotepath, fl, callback)
    File "C:\ProgramData\Anaconda3\lib\site-packages\paramiko\sftp_client.py", line 778, in getfo
    file_size = self.stat(remotepath).st_size
    File "C:\ProgramData\Anaconda3\lib\site-packages\paramiko\sftp_client.py", line 493, in stat
    t, msg = self._request(CMD_STAT, path)
    File "C:\ProgramData\Anaconda3\lib\site-packages\paramiko\sftp_client.py", line 813, in _request
    return self._read_response(num)
    File "C:\ProgramData\Anaconda3\lib\site-packages\paramiko\sftp_client.py", line 865, in _read_response
    self._convert_status(msg)
    File "C:\ProgramData\Anaconda3\lib\site-packages\paramiko\sftp_client.py", line 894, in _convert_status
    raise IOError(errno.ENOENT, text)
    FileNotFoundError: [Errno 2] File does not exist

    通过 get 方法下载带中文名文件时报文件不存在的错,但是下载英文名的文件都是正常的。这次网上真找不到了。。
    求解决方案。。
    6 条回复    2019-11-25 09:59:13 +08:00
    julyclyde
        1
    julyclyde  
       2019-08-19 14:10:55 +08:00
    gb2312 那是你的问题啊
    python3 全都是 utf-8
    warcraft1236
        2
    warcraft1236  
       2019-08-19 14:22:20 +08:00
    @julyclyde Python3 跟 utf-8 没关系吧,我觉得应该有可以指定编码的参数,要不是具体的使用的时候需要的方法里,要不就是初始化 paramiko 的时候
    ft3312591
        3
    ft3312591  
    OP
       2019-08-19 15:54:02 +08:00 via Android
    @julyclyde 不是,服务器端没用 uft-8 的原因,但是本质上是 paramkio 库写的太死,全部都是 utf-8
    piaochen0
        4
    piaochen0  
       2019-10-22 17:33:21 +08:00
    @ft3312591 这个问题我也碰到了,目前网上看的方法都是修改库的源代码,不过这个方法太暴力了,不知道有没有什么更优雅的方法解决这个问题?
    ft3312591
        5
    ft3312591  
    OP
       2019-11-25 09:20:52 +08:00 via Android
    @piaochen0 不算暴力,改的不多还算可控。
    关键是现在文件名中文能正确显示出来了,但是下载该文件的话就报错,不知道该怎么处理。你有什么解决方案吗
    piaochen0
        6
    piaochen0  
       2019-11-25 09:59:13 +08:00
    @ft3312591 我尝试了打算重写部分方法,不过这样反而感觉很奇怪。
    我自己没找到有什么办法能完美替代源代码里部分调用链中的类或者方法。
    所以改的代码比较难看。
    还不如直接改源代码里面的编码。
    不过上头不肯改源代码。
    由于我们是内部的应用,现在是强制有要求服务器目录不能有中文。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5527 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 37ms · UTC 06:51 · PVG 14:51 · LAX 22:51 · JFK 01:51
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.