FTP发送Python的字节流 [英] ftp sending python bytesio stream

查看:1346
本文介绍了FTP发送Python的字节流的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用python ftplib从一个ftp站点发送一个文件到另一个ftp站点,这样可以避免文件的读/写操作。我创建一个BytesIO流:

  myfile = BytesIO()

我成功地从ftp站点检索了一个映像文件,其中包括:

  ftp_one.retrbinary 'RETR P1090080.JPG',myfile.write)

我可以将这个内存对象保存到一个普通的文件:

  fot = open('casab.jpg','wb')

fot = myfile .readvalue()

但是我无法通过ftp和storbinary发送这个流。我认为这可以工作:

pre $ ftp_two.storbinary('STOR magnafoto.jpg',myfile.getvalue())

但是没有。我得到一个很长的错误信息以'buf = fp.read(blocksize)
为结尾'AttributeError:'str'对象没有属性'read'

尝试了许多荒唐的组合,但没有成功。顺便说一下,我对myfoto.write真的很困惑。不应该是myfoto.write()吗?



我对这个缓冲区所做的或者需要的东西也一无所知。我想要的东西太复杂了吗?我应该只是用我的系统中的中间写入/读取乒乓文件?全部



编辑:感谢abanert我得到的东西直。为了记录,storbinary参数是错误的,并且需要myfile.seek(0)在发送之前倒回流。这是一个工作片段,可以在两个ftp地址之间移动一个文件,而无需中间的物理文件写入:

  import ftplib as ftp 
从io导入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()


getvalue()。只要不这样做:

$ p $ $ $ $ c $ ftp_two.storbinary('STOR magnafoto.jpg',myfile)
code>






storbinary 需要一个类似文件的对象,它可以调用<$ c

幸运的是,您只有这样一个对象, myfile BytesIO 。 (从代码中我们不能清楚地看到事情的顺序是什么 - 如果这样做不行,你可能需要 myfile.seek(0)或用另一种模式创建它,但是一个 BytesIO 可以和 storbinary 一起工作,除非你做错了。 / p>

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



因此, code> storbinary 可以调用 read 的文件类对象,您可以给它一个字节对象,这当然与Python 2.x中的 str 相同,并且不能调用 read






对于你们来说:


另外,我对myfoto.write真的很困惑。不应该是myfoto.write()?


请看文档。第二个参数不是文件,它是一个回调函数。


为每个函数调用 callback 函数接收到的数据块,用一个字符串参数给出数据块。

你想要的是一个函数,它附加每一块数据到 myfoto 的结尾。虽然你可以写你自己的函数来做到这一点:$ b​​
$ pre $ def $ callback(block_of_data)
myfoto.write(block_of_data )

...应该很明显,这个函数和<$ c $完全一样c> myfoto.write 方法。所以,你可以传递这个方法本身。



如果你不理解绑定方法,参见方法对象。 $ b

这种灵活性,看起来很奇怪,可以让你做一些比将整个文件下载到缓冲区以发送到另一台服务器更好的方法。您可以同时打开两个连接,并使用回调从源服务器发送到目的服务器的每个缓冲区,因为它已经收到,没有任何超过一个缓冲区存储任何东西。



但是,除非你真的需要这个,否则你可能不想经历那么复杂的事情。其实,一般来说, ftplib 是一种低级的。它有一些设计(例如 storbinary 需要一个文件,而 retrbinary 需要一个回调)感觉在这个低水平,但从更高层次看起来很奇怪。因此,您可能需要通过执行一个在PyPI搜索


I want to send a file with python ftplib, from one ftp site to another, so to avoid file read/write processees.

I create a BytesIO stream:

myfile=BytesIO()

And i succesfully retrieve a image file from ftp site one with retrbinary:

ftp_one.retrbinary('RETR P1090080.JPG', myfile.write)

I can save this memory object to a regular file:

fot=open('casab.jpg', 'wb')

fot=myfile.readvalue()

But i am not able to send this stream via ftp with storbinary. I thought this would work:

ftp_two.storbinary('STOR magnafoto.jpg', myfile.getvalue())

But doesnt. i get a long error msg ending with 'buf = fp.read(blocksize) AttributeError: 'str' object has no attribute 'read'

I also tried many absurd combinations, but with no success. As an aside, I am also quite puzzled with what I am really doing with myfoto.write. Shouldnt it be myfoto.write() ?

I am also quite clueless to what this buffer thing does or require. Is what I want too complicated to achieve? Should I just ping pong the files with an intermediate write/read in my system? Ty all

EDIT: thanks to abanert I got things straight. For the record, storbinary arguments were wrong and a myfile.seek(0) was needed to 'rewind' the stream before sending it. This is a working snippet that moves a file between two ftp addresses without intermediate physical file writes:

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()

解决方案

The problem is that you're calling getvalue(). Just don't do that:

ftp_two.storbinary('STOR magnafoto.jpg', myfile)


storbinary requires a file-like object that it can call read on.

Fortunately, you have just such an object, myfile, a BytesIO. (It's not entirely clear from your code what the sequence of things is here—if this doesn't work as-is, you may need to myfile.seek(0) or create it in a different mode or something. But a BytesIO will work with storbinary unless you do something wrong.)

But instead of passing myfile, you pass myfile.getvalue(). And getvalue "Returns bytes containing the entire contents of the buffer."

So, instead of giving storbinary a file-like object that it can call read on, you're giving it a bytes object, which is of course the same as str in Python 2.x, and you can't call read on that.


For your aside:

As an aside, I am also quite puzzled with what I am really doing with myfoto.write. Shouldnt it be myfoto.write() ?

Look at the docs. The second parameter isn't a file, it's a callback function.

The callback function is called for each block of data received, with a single string argument giving the data block.

What you want is a function that appends each block of data to the end of myfoto. While you could write your own function to do that:

def callback(block_of_data):
    myfoto.write(block_of_data)

… it should be pretty obvious that this function does exactly the same thing as the myfoto.write method. So, you can just pass that method itself.

If you don't understand about bound methods, see Method Objects in the tutorial.


This flexibility, as weird as it seems, lets you do something even better than downloading the whole file into a buffer to send to another server. You can actually open the two connections at the same time, and use callbacks to send each buffer from the source server to the destination server as it's received, without ever storing anything more than one buffer.

But, unless you really need that, you probably don't want to go through all that complexity.

In fact, in general, ftplib is kind of low-level. And it has some designs (like the fact that storbinary takes a file, while retrbinary takes a callback) that make total sense at that low level but seem very odd from a higher level. So, you may want to look at some of the higher-level libraries by doing a search at PyPI.

这篇关于FTP发送Python的字节流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆