import ftplib
import csv
import StringIO
sio = StringIO.StringIO()
data = csv.writer(sio)
data.writerows(data_to_export)
sio.seek(0)
ftps.storbinary("STOR " + 'blah.csv', sio)
ftps.close()
所以我创建的文件只有56行,它创建得很慢。当它完成创建时,我得到这个错误:
ftps.storbinary("STOR " + 'blah.csv', sio)
File "/usr/lib/python2.7/ftplib.py", line 752, in storbinary
conn.unwrap()
File "/usr/lib/python2.7/ssl.py", line 384, in unwrap
s = self._sslobj.shutdown()
SSLError: The read operation timed out
我不明白为什么它这么慢,为什么它会超时,即使它创建了那个文件。
注:请询问我是否需要提供额外的信息
我也尝试过cString
,但它并没有改善任何东西,因为我猜它与写作速度无关。
如果存在差异,则使用隐式SSL/TLS模式连接ftp (ftp不支持显式SSL/TLS)。
更深入的研究。这就是调试ftp的结果:
*cmd* 'TYPE I'
*resp* '200 Binary mode selected.'
*cmd* 'PASV'
*resp* '227 Entering Passive Mode (*,*,*,*,*,*)'
*cmd* 'STOR blah.csv'
*resp* '125 Secure data connection open; transfer starting.'
然后停留在最后一个输出,直到连接超时。
注意。我的网络连接很好,但是那个ftp有点慢。不过我想这么小的文件应该处理得比这快得多。
更新2 这是一个奇怪的ftp。尝试不安全的ftp连接,文件上传正确和快速。这种隐式连接与这种缓慢的性能和超时有关。
关于速度,有太多的因素要猜测,所以我会调整代码并尝试下面的代码,我最近为客户ftp交付创建的,可以声明它的工作没有错误。
注意,这是来自一个更大的文件,但已经提取了相关的部分,所以忽略一些变量,如args。Var,你可能需要根据带宽等来调整块大小,尝试将其降低到1024,然后再向上工作。
希望有帮助
def initiate_ftp_connection(ftp_host, user, passwd, ftp_dir):
ftp_session = ftplib.FTP()
ftp_session.connect(ftp_host, 21)
#uncomment for debugging.
#ftp_session.set_debuglevel(2)
ftp_session.login(user=user,
passwd=passwd)
#cd to correct remote directory
ftp_session.cwd(ftp_dir)
return ftp_session
def upload_deliverables(session, file_and_path):
working_dir = os.path.dirname(file_and_path)
#strip to remove any newlines
filename = os.path.basename(file_and_path).strip()
totalSize = os.path.getsize(file_and_path)
#instantiate progress tracker for status updates
uploadTracker = FtpUploadTracker(int(totalSize),filename)
#change dir to working_dir
os.chdir(working_dir)
'''
Trigger the ftp upload (storbinary) for the deliverable.
Args:
1: FTP KEYWORD and FILE
2: File IO
3: Blocksize
4: Callback
'''
session.storbinary('STOR ' + filename,
open(filename,'r'),
8192,
uploadTracker.ftp_callback)
#connect to server
ftp_session = initiate_ftp_connection(args.ftp_host,
args.ftp_user,
args.ftp_pass,
args.ftp_dir)
#start ftp delivery
upload_deliverables(ftp_session, args.asset)
#quit the ftp session
ftp_session.quit()
#close any file handles.
ftp_session.close()
我在使用python的ftplib.FTP_TLS
, prot_p
和Microsoft FTP服务器时遇到了STORBINARY函数的问题。
的例子:
ftps = FTP_TLS(host,username,password)
ftps.prot_p
STORBINARY...
错误指示打开函数超时。
这与以下问题有关:
https://www.sami-lehtinen.net/blog/python-32-ms-ftps-ssl-tls-lockup-fix https://bugs.python.org/issue10808 https://bugs.python.org/issue34557 决定:
打开ftplib的python页面:https://docs.python.org/3/library/ftplib.html
点击源代码,它会带你到类似这样的地方:https://github.com/python/cpython/blob/3.10/Lib/ftplib.py
创建此代码的副本到您的项目中(示例:
my_libmy_ftplib.py
)对于失败的方法,在您的情况下STORBINARY,错误看起来在该方法中表示
conn.unwrap()
的行上。注释这一行。输入关键字pass
,否则空if
块会导致语法错误。在实例化FTP_TLS的文件中导入上述库。现在您将不会再遇到此错误。
推理:函数def ntransfercmd
中的代码(在FTP_LTS
类下)将conn
对象封装到SSL会话中。上面您所评论的代码行负责在传输后拆除SSL会话。由于某种原因,当使用Microsoft的FTP服务器时,代码在那一行被阻塞并导致超时。这可能是因为服务器在传输后断开了连接,也可能是因为服务器从自己的角度打开了SSL。我不确定。注释这一行是无害的,因为最终连接无论如何都会关闭——详细信息见下文:
在ftplib的python代码中,您将注意到STORBINARY函数中的conn
对象被包含在with
块中,并且它是使用socket.create_connection
创建的。这意味着当代码退出with
块时,会自动调用.close()
(您可以通过查看python套接字类源代码中的__exit__
方法来确认这一点)。