diff options
-rw-r--r-- | paramiko/sftp_client.py | 13 | ||||
-rw-r--r-- | tests/test_sftp.py | 28 |
2 files changed, 37 insertions, 4 deletions
diff --git a/paramiko/sftp_client.py b/paramiko/sftp_client.py index 93190d85..88e6eee0 100644 --- a/paramiko/sftp_client.py +++ b/paramiko/sftp_client.py @@ -758,7 +758,7 @@ class SFTPClient(BaseSFTP, ClosingContextManager): with open(localpath, "rb") as fl: return self.putfo(fl, remotepath, file_size, callback, confirm) - def getfo(self, remotepath, fl, callback=None): + def getfo(self, remotepath, fl, callback=None, prefetch=True): """ Copy a remote file (``remotepath``) from the SFTP server and write to an open file or file-like object, ``fl``. Any exception raised by @@ -771,18 +771,21 @@ class SFTPClient(BaseSFTP, ClosingContextManager): :param callable callback: optional callback function (form: ``func(int, int)``) that accepts the bytes transferred so far and the total bytes to be transferred + :param bool prefetch: + option to deactivate prefetching :return: the `number <int>` of bytes written to the opened file object .. versionadded:: 1.10 """ file_size = self.stat(remotepath).st_size with self.open(remotepath, "rb") as fr: - fr.prefetch(file_size) + if prefetch: + fr.prefetch(file_size) return self._transfer_with_callback( reader=fr, writer=fl, file_size=file_size, callback=callback ) - def get(self, remotepath, localpath, callback=None): + def get(self, remotepath, localpath, callback=None, prefetch=True): """ Copy a remote file (``remotepath``) from the SFTP server to the local host as ``localpath``. Any exception raised by operations will be @@ -793,13 +796,15 @@ class SFTPClient(BaseSFTP, ClosingContextManager): :param callable callback: optional callback function (form: ``func(int, int)``) that accepts the bytes transferred so far and the total bytes to be transferred + :param bool prefetch: + option to deactivate prefetching .. versionadded:: 1.4 .. versionchanged:: 1.7.4 Added the ``callback`` param """ with open(localpath, "wb") as fl: - size = self.getfo(remotepath, fl, callback) + size = self.getfo(remotepath, fl, callback, prefetch) s = os.stat(localpath) if s.st_size != size: raise IOError( diff --git a/tests/test_sftp.py b/tests/test_sftp.py index e4e18e5a..3a5224c9 100644 --- a/tests/test_sftp.py +++ b/tests/test_sftp.py @@ -554,6 +554,34 @@ class TestSFTP(object): os.unlink(localname) sftp.unlink(sftp.FOLDER + "/bunny.txt") + def test_get_without_prefetch(self, sftp): + """ + Create a 4MB file. Verify that pull works without prefetching + using a lager file. + """ + + sftp_filename = sftp.FOLDER + "/dummy_file" + num_chars = 1024 * 1024 * 4 + + fd, localname = mkstemp() + os.close(fd) + + with open(localname, 'wb') as f: + f.write(b'0' * num_chars) + + sftp.put(localname, sftp_filename) + + os.unlink(localname) + fd, localname = mkstemp() + os.close(fd) + + sftp.get(sftp_filename, localname, prefetch=False) + + assert os.stat(localname).st_size == num_chars + + os.unlink(localname) + sftp.unlink(sftp_filename) + def test_check(self, sftp): """ verify that file.check() works against our own server. |