Найти - Пользователи
Полная версия: ftplib не закачивает текстовый файл
Начало » Network » ftplib не закачивает текстовый файл
1
Игнат
скрипт на питоне2 прекрасно скачивает файл с фтп, сохраняет его в локальный файл и снова закачивает на сервер
но при запуске на питоне3 - вылазит эксепшен

# файл скачали в файл tmp, все отлично
# без изменений пробуем закачать:
file = open('tmp', 'rt')
ftp.storlines('STOR module1.php', file)
file.close()
экспешн:
  File "/usr/local/lib/python3.2/ftplib.py", line 488, in storlines
if buf[-1] in B_CRLF: buf = buf[:-1]
TypeError: Type str doesn't support the buffer API
в исходнике ftplib.py мы видим как питон удаляет имеющиеся переводы строк и добавляет свои, обращаясь к строке через срез:
def storlines(self, cmd, fp, callback=None)
...
while 1:
buf = fp.readline()
if not buf: break
if buf[-2:] != B_CRLF:
if buf[-1] in B_CRLF: buf = buf[:-1]
buf = buf + B_CRLF
почему строки из файла для него вдруг оказываются не имеющими срезов?? причем именно в <b>питон3</b>?

при этом в том же коде:
        file = open('tmp', 'rt')
f = file.readline()
print(f[0:2])
работает!

никак не могу найти различий между двумя скриптами, лежащими в соседних папках. почему один работает, а другой нет.
Игнат
от безысходности пока закачиваю через binary mode
и судя по этому сообщению - http://stackoverflow.com/questions/540342/python-3-0-urllib-parse-error-type-str-doesnt-support-the-buffer-api - если я его правильно понял, это баг питона
Андрей Светлов
file = open('tmp', ‘rb’)
Игнат
ну да, я так и делаю
но что это за баг? почему второй питон заливает текстовые файлы, а третий нет?
Андрей Светлов
Не называйте ваши кривые руки багом.

В чем отличие между файлом, открытом в текстовом и бинарном режиме?
Чем отличаются str и bytes?
Что получится в результате ‘a’ + b'b' ?
Игнат
багом назвал не я, а автор топика, на который я сослался
за 5 лет кодинга на пхп не припомню, чтобы я когда-нибудь мог вообще предположить, что причина ошибок не я, а интерпретатор

на ваши вопросы ответить толком не могу
заметил лишь то, что ‘a’ + b'b' в питон2 дает ‘ab’, а в питон3 - эксепшен
но почему - не понимаю
Андрей Светлов
потому что разные типы: str и bytes. Их специально развели по разным углам и затруднили совместную работу.
str - это строка юникодных символов. bytes - просто байты. Или строка в какой-нибудь кодировке.
Именно потому, что кодировки бывают разные - преобразовывать нужно явно через .decode/.encode.
В python 2 такой проблемы нет. Зато есть более фундаментальная - посмотрите, сколько на этом форуме по кодировкам вопросов задают.
Файл, открытый в тексте будет читать str. Бинарный - bytes.
Фабрика open возвращает экземпляры разных классов.
Игнат
тем не менее, это нисколько не приоткрывает завесу тайны - почему на фтп не закачивается текстовый файл, открытый как текст в текстовом режиме через storlines?

какое значение тут может иметь кодировка? в какой файл читается - в такой сервер и должен сохранять, разве нет?
Андрей Светлов
Именно потому, что ftp сервер не заботится о кодировке - так называемые текстовые файлы в ftp (storlines/retrlines) на самом деле работают как бинарные с одним единственным исключением - принимают конец строки в любом виде (LF, CR, CRLF). Во всех остальных аспектах это байты. Собственно говоря ftp ничего не говорит о тексте - есть lines mode и binary mode. lines mode заменяет концы строк так, чтобы они было CRLF. binary mode этого преобразования не делает.
Есть еще и то, как работает ftp server.
lines mode - TYPE A, ascii bytes. Т.е. спецификация явно запрещает пересылку не ascii текста (в то время как сервера обычно позволяют). Старайтесь не использовать этот режим до тех пор, пока не будете точно знать что вы делаете.
binary mode - TYPE I, image. Просто байты как есть, без всяких ограничений. Именно то, что нужно.
Еще есть несколько вариантов команды TYPE, совсем экзотических. Все они никому сейчас не нужны (как и TYPE A на самом деле).

Не уверен, понятно ли изложил но лучше у меня не получилось.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB