Python ftplib UnicodeEncodeError при попытке загрузить XML с содержимым Unicode

Я пытаюсь загрузить XML с содержимым Unicode на FTP-сервер с помощью ftplib, но получаю следующее исключение, когда пытаюсь загрузить метод using storbinary. XML-данные правильно закодированы в unicode (utf-8), я в этом убедился, я не уверен, почему storbinary пытается кодировать его в ascii при загрузке. Кто-нибудь может помочь?


--> 429         ftp.storbinary("STOR file.xml", xml)
    430 
    431     def run(self):

/usr/lib/python2.7/ftplib.pyc in storbinary(self, cmd, fp, blocksize, callback, rest)
    463             buf = fp.read(blocksize)
    464             if not buf: break
--> 465             conn.sendall(buf)
    466             if callback: callback(buf)
    467         conn.close()

/usr/lib/python2.7/socket.pyc in meth(name, self, *args)
    222 
    223 def meth(name,self,*args):
--> 224     return getattr(self._sock,name)(*args)
    225 
    226 for _m in _socketmethods:

UnicodeEncodeError: 'ascii' codec can't encode character u'\xae' in position 3368: ordinal not in range(128)


person asp    schedule 24.02.2013    source источник
comment
Похоже, это объект unicode, поэтому он вообще не закодирован.   -  person Cairnarvon    schedule 24.02.2013
comment
xml - файловый объект? В противном случае используйте StringIO для создания файлового объекта из вашей XML-строки.   -  person Austin Phillips    schedule 24.02.2013
comment
@AustinPhillips: Да, я создаю XML и использую объект StringIO, чтобы передать его ftplib.   -  person asp    schedule 24.02.2013
comment
@Cairnarvon: я не понял, что вы имели в виду, строка, которую я пишу в экземпляр StringIO, является экземпляром unicode, и просто убедитесь в кодировке, я даже попытался добавить .encode (utf-8) в строку перед записью в объект StringIO.   -  person asp    schedule 24.02.2013
comment
@asp Приведите минимальный пример, показывающий создание строки Unicode.   -  person Austin Phillips    schedule 25.02.2013
comment
@AustinPhillips, пожалуйста, найдите код ниже; Комментарии, кажется, удаляют мое форматирование, ссылка pastebin ниже; pastebin.com/GugTLRQJ   -  person asp    schedule 03.03.2013


Ответы (2)


Вы должны передать файл, открытый в двоичном режиме, в ftp.storbinary(). Например, если вы хотите загрузить строку Unicode как файл filename:

import io

assert isinstance(unicode_string, unicode)
file = io.BytesIO(unicode_string.encode("utf-8"))
ftp.storbinary("STOR filename", file)

Если unicode_string содержит xml; убедитесь, что кодировка символов, используемая в объявлении xml, соответствует кодировке, которую вы используете для хранения файла.

person jfs    schedule 24.02.2013
comment
Я использую экземпляр StrinIO для перехода к storbinary методу. - person asp; 24.02.2013
comment
@asp: StringIO работает как со строками Unicode, так и со строками байтов в Python 2. Используйте BytesIO, чтобы явно указать, что разрешены только байты. - person jfs; 24.02.2013

Мне удалось найти решение, комментарий @Cairnarvon был частично правильным, я кодировал строку, но были другие биты строки, записанные в экземпляр StringIO, которые не были закодированы. В конце концов, я создал бит XML и закодировал его как единое целое. Вы можете увидеть мой код по ссылке pastebin ниже;

http://pastebin.com/GugTLRQJ

person asp    schedule 03.03.2013