问题
I have a large xml file stored in a variable. I want to write it directly to an ftp using pysftp. I believe I need to use the pysftp.putfo and this needs a file like object. Here is a minimal example:
from io import StringIO
from pysftp import Connection, CnOpts
cnopts = CnOpts()
cnopts.hostkeys = None
with Connection('localhost'
,username= 'admin'
,password = 'test'
,cnopts=cnopts
) as sftp:
sftp.putfo(StringIO('xml string'))
I get the following error:
TypeError: Expected unicode or bytes, got None
What am I doing wrong? And is there maybe a simpler and better way of achieving my goal of writing a string variable to a file on an ftp?
回答1:
Your first approach was valid, just specify a filename. In-memory files have no default names, and pysftp doesn't know how to name destination file.
from io import StringIO
from pysftp import Connection
with Connection('localhost', ...) as sftp:
sftp.putfo(StringIO('xml string'), 'test.txt')
It should just work. Also, as a side note - Paramiko (library used by pysftml) put
operation is under the hood calling putfo
, it's just a thin wrapper. So from the server perspective, it's totally transparent if a file was uploaded directly from FS or from memory.
回答2:
I have found one solution, not sure is the best:
from io import StringIO
from pysftp import Connection, CnOpts
cnopts = CnOpts()
cnopts.hostkeys = None
with Connection('localhost'
,username= 'admin'
,password = 'test'
,cnopts=cnopts
) as sftp:
f = sftp.open('/folder/filename.xml', 'wb')
f.write('xml string')
Edit: Discovered why there is no good solution for this. Most FTP-servers will demand that you put a file directly, probably to avoid an undending stream. So my final solution was to create the file locally and use pysft put().
来源:https://stackoverflow.com/questions/49937893/how-to-write-a-string-to-file-on-ftp-with-pysftp