【发布时间】:2014-09-09 00:43:32
【问题描述】:
我希望从 python 将文本直接写入我的 FTP 站点,而不存储临时文件 在磁盘上, 类似:
ftp = FTP('ftp.mysite.com')
ftp.login('un','pw')
ftp.cwd('/')
ftp.storbinary('STOR myfile.html', 'text to store', 'rb')
这甚至可能吗? 非常感谢。
【问题讨论】:
我希望从 python 将文本直接写入我的 FTP 站点,而不存储临时文件 在磁盘上, 类似:
ftp = FTP('ftp.mysite.com')
ftp.login('un','pw')
ftp.cwd('/')
ftp.storbinary('STOR myfile.html', 'text to store', 'rb')
这甚至可能吗? 非常感谢。
【问题讨论】:
正如the docs 所说:
以二进制传输模式存储文件。 cmd 应该是一个合适的
STOR命令:"STOR filename"。 file 是一个文件对象(以二进制模式打开),使用其read()方法在大小为 blocksize 的块中读取直到 EOF,以提供要存储的数据……
因此,您需要使用适当的read 方法为其提供一个类似文件的对象。
字符串不是类似文件的对象,但io.BytesIO 是。所以:
import io
bio = io.BytesIO(b'text to store')
ftp.storbinary('STOR myfile.html', bio)
另外,请注意我没有传递 'rb' 参数。 storbinary 的第三个参数是blocksize,'rb' 显然不是有效的块大小。
如果您需要使用 Python 2.5 或更早版本,请参阅 Dan Lenski 的回答。
如果您需要使用 Python 2.6-2.7,并且类文件对象的性能很重要(这里不存在,但在某些情况下可能存在),并且您只关心 CPython,使用他的答案,但用cStringIO 代替StringIO。 (普通的 StringIO 在 2.x 中很慢,而 io.BytesIO 在 3.3 之前甚至更慢。)
【讨论】:
bio = io.BytesIO('text to store'.encode('utf-8'))
您是否尝试过使用StringIO object,它像文件一样嘎嘎作响,但只是一个字符串?
from ftplib import *
import StringIO
ftp = FTP('ftp.mysite.com')
ftp.login('un','pw')
ftp.cwd('/')
ftp.storbinary('STOR myfile.html', StringIO.StringIO('text to store'))
编辑:@abarnert's answer 是 Python3 的等价物。我的是 Python2 版本。
【讨论】:
io 在 2.6 和 2.7 中的效果与在 3.x 中一样好。因此,除非您需要 2.5 兼容性,否则没有理由使用旧版本。
functools.lru_cache 一直在诱使我咬住 Unicode 子弹,暂时转到 3.x。
lru_cache 是纯 Python,它几乎可以在 2.6+ 中开箱即用,并且有一个向后移植2.4+。但是yield from、pip 引导程序、内置venv、tracemalloc、asyncio、selectors、永远不会被反向移植的错误修复和优化、更理智和更详细的异常层次结构、链接异常、@ 987654335@,具有实际 argspecs 的 C 函数,改进了 inspect,concurrent.futures,……此外,一旦你咬紧牙关,正确的 Unicode 是一个加分项,而不是一个绊脚石。
yield from 和 importlib 是吸引我的其他人……lru_cache 只是我最近对 Py3k 嫉妒的一个例子。