diff -r 001895c39fea Doc/library/ftplib.rst --- a/Doc/library/ftplib.rst Wed Jun 11 03:54:30 2014 +0200 +++ b/Doc/library/ftplib.rst Wed Jun 11 14:26:51 2014 +0200 @@ -266,11 +266,14 @@ Store a file in binary transfer mode. *cmd* should be an appropriate ``STOR`` command: ``"STOR filename"``. *file* is a :term:`file object` - (opened in binary mode) which is read until EOF using its :meth:`~io.IOBase.read` - method in blocks of size *blocksize* to provide the data to be stored. - The *blocksize* argument defaults to 8192. *callback* is an optional single - parameter callable that is called on each block of data after it is sent. - *rest* means the same thing as in the :meth:`transfercmd` method. + (opened in binary mode) which is read until EOF. *blocksize* tells how many + bytes to read from the file on each iteration. *callback* is an optional + single parameter callable that is called on each block of data after it is + sent. *rest* means the same thing as in the :meth:`transfercmd` method. + If :func:`os.sendfile` is available and *callback* is not specified this + method will use high-performance :func:`os.sendfile` function to send the + file in which case *blocksize* will be ignored. + .. versionchanged:: 3.2 *rest* parameter added. diff -r 001895c39fea Lib/ftplib.py --- a/Lib/ftplib.py Wed Jun 11 03:54:30 2014 +0200 +++ b/Lib/ftplib.py Wed Jun 11 14:26:51 2014 +0200 @@ -501,15 +501,19 @@ """ self.voidcmd('TYPE I') with self.transfercmd(cmd, rest) as conn: - while 1: - buf = fp.read(blocksize) - if not buf: - break - conn.sendall(buf) - if callback: - callback(buf) + using_ssl = _SSLSocket is not None and isinstance(conn, _SSLSocket) + if callback or using_ssl: + while 1: + buf = fp.read(blocksize) + if not buf: + break + conn.sendall(buf) + if callback: + callback(buf) + else: + conn.sendfile(fp) # shutdown ssl layer - if _SSLSocket is not None and isinstance(conn, _SSLSocket): + if using_ssl: conn.unwrap() return self.voidresp()