【问题标题】:Uploading files from a Cyrillic path using pycurl使用 pycurl 从 Cyrillic 路径上传文件
【发布时间】:2011-06-21 16:06:00
【问题描述】:

我最近设计了一个由 PyCURL 支持的上传对话框,我在一些应用程序中使用了它。
我在设置 pycurl 的 HTTPPOST 选项时遇到了问题。我是这样设置的:
self.curl.setopt(self.curl.HTTPPOST, [(field, (self.curl.FORM_FILE, filename))])
如果文件名是一个字符串,一切都很好。但是,如果我向它传递一个 unicode,它会引发一个 TypeError。 我有什么办法可以给它一条西里尔字母的路径吗?我尝试了 UTF-8 编码,但没有成功。 感谢您的宝贵时间

更新:

我实际上是从 WX 控件获取文件名,所以在我触摸它之前它是 unicode。然后当我将其编码为 UTF-8 时(使用 filename = filename.encode('UTF-8')),setopt 运行良好,但在执行时一切都崩溃了:

* About to connect() to example.com port 80 (#0)
*   Trying 123.123.123.123... * connected
* Connected to example.com (123.123.123.123) port 80 (#0)
* failed creating formpost data
* Connection #0 to host example.com left intact
Traceback (most recent call last):
  File "c:\python27\lib\site-packages\transfer_dialogs-0.28-py2.7.egg\transfer_dialogs\transfer_dialogs.py", line 64, in perform_transfer
    self.curl.perform()
error: (26, 'failed creating formpost data')

更新 2:

根据要求,提供更多数据。文件名包含打开对话框中 GetValue() 的结果。
logging.debug("文件名: %r 编码文件名: %r" % (filename, filename.encode('UTF-8')))
结果:
2011 年 2 月 5 日星期六 03:33:56 core.dialogs.upload_audio 调试:文件名:u'C:\Users\Q\test\\u0422\u0435\u0441\u0442\u043e\u0432\u0430\u044f \u043f\u0430 \u043f\u043a\u0430\test.mp3' 编码文件名:'C:\Users\Q\test\\xd0\xa2\xd0\xb5\xd1\x81\xd1\x82\xd0\xbe\xd0\xb2\xd0 \xb0\xd1\x8f \xd0\xbf\xd0\xb0\xd0\xbf\xd0\xba\xd0\xb0\test.mp3'

【问题讨论】:

  • “我尝试了 UTF-8 编码,但没有成功”——解释你是如何尝试的,结果是什么:乱码、异常(回溯会有所帮助)、其他)。另外:什么是“西里尔路径”?以例如编码的文件名/路径cp1251?您使用的是什么操作系统?
  • 我尝试使用 filename = filename.encode('UTF-8')。然后引发了设置 HTTPPOST 选项的行:error: (26, 'failed created formpost data') OS Windows。路径类似于:r"C:\Users\Q\test\Тестовая папка\test.mp3"
  • 请不要使用something_like(filename),而是使用repr() 明确显示您从wx 控件获得的unicode 文件名。
  • @John 按要求:logging.debug("Filename: %r encoded filename: %r" % (filename, filename.encode('UTF-8'))) 结果:2 月 5 日星期六, 2011 03:33:56 core.dialogs.upload_audio 调试:文件名:u'C:\\Users\\Q\\test\\\u0422\u0435\u0441\u0442\u043e\u0432\u0430\u044f \u043f\u0430 \u043f\u043a\u0430\\test.mp3' 编码文件名:'C:\\Users\\Q\\test\\\xd0\xa2\xd0\xb5\xd1\x81\xd1\x82\xd0\xbe\ xd0\xb2\xd0\xb0\xd1\x8f \xd0\xbf\xd0\xb0\xd0\xbf\xd0\xba\xd0\xb0\\test.mp3'
  • 谢谢。没有奇怪的字符;只有 ASCII 和西里尔文。尝试的事情:编写一个小的独立脚本,尝试打开文件名 3 次(作为 unicode,编码为 UTF,编码为 cp1251)。您系统上的“ANSI”编码是什么?请注意,文件名中有一个空格。应用程序可以处理带有 ASCII 字符和空格的文件名吗?您确定磁盘上实际文件的名称是从 wx 控件接收到的吗?

标签: python unicode pycurl


【解决方案1】:

文件名应该是 UTF-8,并且你上传到的主机应该支持 UTF-8 文件名。如果它支持不同的非 Unicode 编码,请尝试对文件名 KOI8-R 或 WIN1251 进行编码(但这当然不是很好且不符合标准)。

编辑,看过 cmets:可能应该是 ur"C:\Users\Q\test\Тестовая папка\test.mp3".encode("UTF-8")u 有点重要;没有它,西里尔字母会在您的控制台编码中进行编码。我只是试了一下,它成功了(不是上传,只是setopt)。

【讨论】:

  • 当我将文件名编码为 UTF-8 时,我得到:error: (26, 'failed created formpost data') with the HTTPPOST line。
【解决方案2】:

把这个问题分解成2个部分:

  1. 告诉pycurl打开哪个文件来读取文件数据
  2. 将正确编码的文件名发送到服务器

这些可能是也可能不是相同的编码。

对于 1,使用 sys.getfilesystemencoding() 将 unicode 文件名(您在整个 python 代码中正确使用)转换为 pycurl/libcurl 可以使用 fopen() 正确打开的字符串。使用 strace (linux) 或等效的 windows osx 来验证 pycurl 是否打开了正确的文件路径。

如果完全失败,您始终可以通过 pycurl.READFUNCTION 从 Python 提供文件数据流。

对于2,了解文件上传过程中如何传输文件名,example。我没有一个好的链接,我只知道这不是微不足道的,例如当涉及到非常长的文件名时。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-18
    • 2016-11-18
    • 2015-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多