首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >ftp发送python bytesio流

ftp发送python bytesio流
EN

Stack Overflow用户
提问于 2013-06-07 19:42:19
回答 1查看 7.9K关注 0票数 11

我希望用python从一个ftp站点发送一个文件到另一个ftp站点,以避免文件读/写过程。

我创建一个BytesIO流:

代码语言:javascript
运行
复制
myfile=BytesIO()

我成功地从ftp站点检索了一个图像文件,其中一个文件带有retrbinary:

代码语言:javascript
运行
复制
ftp_one.retrbinary('RETR P1090080.JPG', myfile.write)

我可以将这个内存对象保存到一个常规文件中:

代码语言:javascript
运行
复制
fot=open('casab.jpg', 'wb')

fot=myfile.readvalue()

但我无法通过ftp发送此流,并使用storbinary。我以为这会成功的:

代码语言:javascript
运行
复制
ftp_two.storbinary('STOR magnafoto.jpg', myfile.getvalue())

但事实并非如此。我得到了一个长错误消息,结尾为'buf =fp.read(块大小) AttributeError:'str‘对象没有属性'read’

我也尝试过许多荒谬的组合,但都没有成功。顺便说一句,我也很困惑我到底在用myfoto.write做什么。是不是应该是myfoto.write()?

我也完全不知道这个缓冲设备做什么或需要什么。我想要的东西太复杂了吗?我应该只是在我的系统中用中间写/读的文件打乒乓球吗?泰尔

编辑:多亏了阿班纳特,我把事情搞清楚了。为了记录在案,存储二进制参数是错误的,在发送流之前需要一个myfile.seek(0)来“倒带”流。这是一个工作片段,它在两个ftp地址之间移动一个文件,而没有中间物理文件写入:

代码语言:javascript
运行
复制
import ftplib as ftp
from io import BytesIO

ftp_one=ftp.FTP(address1, user1, pass1)
ftp_two=ftp.FTP(address2, user2, pass2)
myfile=BytesIO()
ftp_one.retrbinary ('RETR imageoldname.jpg', myfile.write)
myfile.seek(0)
ftp_two.storbinary('STOR imagenewname.jpg', myfile)
ftp_one.close()
ftp_two.close()
myfile.close()
EN

回答 1

Stack Overflow用户

发布于 2013-06-07 19:47:58

问题是你要打电话给getvalue()。别这么做:

代码语言:javascript
运行
复制
ftp_two.storbinary('STOR magnafoto.jpg', myfile)

storbinary需要一个可以调用read的类似文件的对象。

幸运的是,您有这样一个对象,myfile,一个BytesIO。(从您的代码中还不完全清楚这里的顺序是什么--如果这不能按原样工作,您可能需要以不同的模式或其他方式创建它。但是,除非您做错了什么,否则BytesIO将与storbinary一起工作。)

但不是传递myfile,而是传递myfile.getvalue()。和getvalue“返回包含缓冲区全部内容的bytes

因此,您不是为storbinary提供一个可以调用read的类似文件的对象,而是给它一个bytes对象,这当然与Python2.x中的str相同,而且您不能在此上调用read

为了你的旁白:

顺便说一句,我也很困惑我到底在用myfoto.write做什么。是不是应该是myfoto.write()?

看看医生们。第二个参数不是文件,而是回调函数。

对接收到的每个数据块调用回调函数,其中一个字符串参数给出数据块。

您需要的是将每个数据块附加到myfoto末尾的函数。虽然您可以编写自己的函数来实现这一点:

代码语言:javascript
运行
复制
def callback(block_of_data):
    myfoto.write(block_of_data)

…很明显,这个函数与myfoto.write方法执行的任务完全相同。因此,您只需传递该方法本身。

如果您不了解绑定方法,请参阅本教程中的方法对象

这种灵活性看起来很奇怪,它允许您做一些比将整个文件下载到缓冲区发送到另一台服务器更好的事情。实际上,您可以同时打开这两个连接,并使用回调将每个缓冲区从源服务器发送到接收到的目标服务器,而不需要存储多个缓冲区。

但是,除非你真的需要,否则你可能不想经历那么复杂的事情。

事实上,总的来说,ftplib是低水平的.而且它有一些设计(比如storbinary接受一个文件,而retrbinary接受一个回调),这些设计在那么低的级别上是完全有意义的,但从更高的层次上看似乎很奇怪。因此,您可能需要通过执行一个在PyPI搜索来查看一些较高级别的库。

票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16991819

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档