Уведомления

Группа в Telegram: @pythonsu

#1 Янв. 28, 2011 11:59:35

Игнат
От:
Зарегистрирован: 2010-10-02
Сообщения: 224
Репутация: +  0  -
Профиль   Отправить e-mail  

ftplib не закачивает текстовый файл

скрипт на питоне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])
работает!

никак не могу найти различий между двумя скриптами, лежащими в соседних папках. почему один работает, а другой нет.



Офлайн

#2 Янв. 28, 2011 12:05:35

Игнат
От:
Зарегистрирован: 2010-10-02
Сообщения: 224
Репутация: +  0  -
Профиль   Отправить e-mail  

ftplib не закачивает текстовый файл

от безысходности пока закачиваю через binary mode
и судя по этому сообщению - http://stackoverflow.com/questions/540342/python-3-0-urllib-parse-error-type-str-doesnt-support-the-buffer-api - если я его правильно понял, это баг питона



Офлайн

#3 Янв. 28, 2011 12:05:51

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

ftplib не закачивает текстовый файл

file = open('tmp', ‘rb’)



Офлайн

#4 Янв. 28, 2011 13:22:31

Игнат
От:
Зарегистрирован: 2010-10-02
Сообщения: 224
Репутация: +  0  -
Профиль   Отправить e-mail  

ftplib не закачивает текстовый файл

ну да, я так и делаю
но что это за баг? почему второй питон заливает текстовые файлы, а третий нет?



Офлайн

#5 Янв. 28, 2011 18:42:05

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

ftplib не закачивает текстовый файл

Не называйте ваши кривые руки багом.

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



Офлайн

#6 Янв. 29, 2011 15:20:28

Игнат
От:
Зарегистрирован: 2010-10-02
Сообщения: 224
Репутация: +  0  -
Профиль   Отправить e-mail  

ftplib не закачивает текстовый файл

багом назвал не я, а автор топика, на который я сослался
за 5 лет кодинга на пхп не припомню, чтобы я когда-нибудь мог вообще предположить, что причина ошибок не я, а интерпретатор

на ваши вопросы ответить толком не могу
заметил лишь то, что ‘a’ + b'b' в питон2 дает ‘ab’, а в питон3 - эксепшен
но почему - не понимаю



Офлайн

#7 Янв. 29, 2011 17:48:12

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

ftplib не закачивает текстовый файл

потому что разные типы: str и bytes. Их специально развели по разным углам и затруднили совместную работу.
str - это строка юникодных символов. bytes - просто байты. Или строка в какой-нибудь кодировке.
Именно потому, что кодировки бывают разные - преобразовывать нужно явно через .decode/.encode.
В python 2 такой проблемы нет. Зато есть более фундаментальная - посмотрите, сколько на этом форуме по кодировкам вопросов задают.
Файл, открытый в тексте будет читать str. Бинарный - bytes.
Фабрика open возвращает экземпляры разных классов.



Офлайн

#8 Фев. 2, 2011 07:04:56

Игнат
От:
Зарегистрирован: 2010-10-02
Сообщения: 224
Репутация: +  0  -
Профиль   Отправить e-mail  

ftplib не закачивает текстовый файл

тем не менее, это нисколько не приоткрывает завесу тайны - почему на фтп не закачивается текстовый файл, открытый как текст в текстовом режиме через storlines?

какое значение тут может иметь кодировка? в какой файл читается - в такой сервер и должен сохранять, разве нет?



Отредактировано (Фев. 2, 2011 07:05:39)

Офлайн

#9 Фев. 2, 2011 07:29:01

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

ftplib не закачивает текстовый файл

Именно потому, что 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 на самом деле).

Не уверен, понятно ли изложил но лучше у меня не получилось.



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version