diff options
author | Jeremy T. Bouse <jbouse@debian.org> | 2013-05-25 00:04:32 -0400 |
---|---|---|
committer | Jeremy T. Bouse <jbouse@debian.org> | 2013-05-25 00:04:32 -0400 |
commit | 1a716ed46d1d556d4ba6798608ab498320acd886 (patch) | |
tree | dbcb23de26387e312f7ea09085330eca90e15853 /paramiko/sftp_client.py | |
parent | a88b8c8c0f591a3bfa8d7984343a27815184f495 (diff) | |
download | python-paramiko-1a716ed46d1d556d4ba6798608ab498320acd886.tar python-paramiko-1a716ed46d1d556d4ba6798608ab498320acd886.tar.gz |
Imported Upstream version 1.10.1upstream/1.10.1
Diffstat (limited to 'paramiko/sftp_client.py')
-rw-r--r-- | paramiko/sftp_client.py | 138 |
1 files changed, 96 insertions, 42 deletions
diff --git a/paramiko/sftp_client.py b/paramiko/sftp_client.py index 79a7761..17ea493 100644 --- a/paramiko/sftp_client.py +++ b/paramiko/sftp_client.py @@ -198,7 +198,7 @@ class SFTPClient (BaseSFTP): Open a file on the remote server. The arguments are the same as for python's built-in C{file} (aka C{open}). A file-like object is returned, which closely mimics the behavior of a normal python file - object. + object, including the ability to be used as a context manager. The mode indicates how the file is to be opened: C{'r'} for reading, C{'w'} for writing (truncating an existing file), C{'a'} for appending, @@ -533,6 +533,56 @@ class SFTPClient (BaseSFTP): """ return self._cwd + def putfo(self, fl, remotepath, file_size=0, callback=None, confirm=True): + """ + Copy the contents of an open file object (C{fl}) to the SFTP server as + C{remotepath}. Any exception raised by operations will be passed through. + + The SFTP operations use pipelining for speed. + + @param fl: opened file or file-like object to copy + @type localpath: object + @param remotepath: the destination path on the SFTP server + @type remotepath: str + @param file_size: optional size parameter passed to callback. If none is + specified, size defaults to 0 + @type file_size: int + @param callback: optional callback function that accepts the bytes + transferred so far and the total bytes to be transferred + (since 1.7.4) + @type callback: function(int, int) + @param confirm: whether to do a stat() on the file afterwards to + confirm the file size (since 1.7.7) + @type confirm: bool + + @return: an object containing attributes about the given file + (since 1.7.4) + @rtype: SFTPAttributes + + @since: 1.4 + """ + fr = self.file(remotepath, 'wb') + fr.set_pipelined(True) + size = 0 + try: + while True: + data = fl.read(32768) + fr.write(data) + size += len(data) + if callback is not None: + callback(size, file_size) + if len(data) == 0: + break + finally: + fr.close() + if confirm: + s = self.stat(remotepath) + if s.st_size != size: + raise IOError('size mismatch in put! %d != %d' % (s.st_size, size)) + else: + s = SFTPAttributes() + return s + def put(self, localpath, remotepath, callback=None, confirm=True): """ Copy a local file (C{localpath}) to the SFTP server as C{remotepath}. @@ -562,29 +612,46 @@ class SFTPClient (BaseSFTP): file_size = os.stat(localpath).st_size fl = file(localpath, 'rb') try: - fr = self.file(remotepath, 'wb') - fr.set_pipelined(True) - size = 0 - try: - while True: - data = fl.read(32768) - if len(data) == 0: - break - fr.write(data) - size += len(data) - if callback is not None: - callback(size, file_size) - finally: - fr.close() + return self.putfo(fl, remotepath, os.stat(localpath).st_size, callback, confirm) finally: fl.close() - if confirm: - s = self.stat(remotepath) - if s.st_size != size: - raise IOError('size mismatch in put! %d != %d' % (s.st_size, size)) - else: - s = SFTPAttributes() - return s + + def getfo(self, remotepath, fl, callback=None): + """ + Copy a remote file (C{remotepath}) from the SFTP server and write to + an open file or file-like object, C{fl}. Any exception raised by + operations will be passed through. This method is primarily provided + as a convenience. + + @param remotepath: opened file or file-like object to copy to + @type remotepath: object + @param fl: the destination path on the local host or open file + object + @type localpath: str + @param callback: optional callback function that accepts the bytes + transferred so far and the total bytes to be transferred + (since 1.7.4) + @type callback: function(int, int) + @return: the number of bytes written to the opened file object + + @since: 1.4 + """ + fr = self.file(remotepath, 'rb') + file_size = self.stat(remotepath).st_size + fr.prefetch() + try: + size = 0 + while True: + data = fr.read(32768) + fl.write(data) + size += len(data) + if callback is not None: + callback(size, file_size) + if len(data) == 0: + break + finally: + fr.close() + return size def get(self, remotepath, localpath, callback=None): """ @@ -603,25 +670,12 @@ class SFTPClient (BaseSFTP): @since: 1.4 """ - fr = self.file(remotepath, 'rb') file_size = self.stat(remotepath).st_size - fr.prefetch() + fl = file(localpath, 'wb') try: - fl = file(localpath, 'wb') - try: - size = 0 - while True: - data = fr.read(32768) - if len(data) == 0: - break - fl.write(data) - size += len(data) - if callback is not None: - callback(size, file_size) - finally: - fl.close() + size = self.getfo(remotepath, fl, callback) finally: - fr.close() + fl.close() s = os.stat(localpath) if s.st_size != size: raise IOError('size mismatch in get! %d != %d' % (s.st_size, size)) @@ -641,13 +695,13 @@ class SFTPClient (BaseSFTP): msg = Message() msg.add_int(self.request_number) for item in arg: - if type(item) is int: + if isinstance(item, int): msg.add_int(item) - elif type(item) is long: + elif isinstance(item, long): msg.add_int64(item) - elif type(item) is str: + elif isinstance(item, str): msg.add_string(item) - elif type(item) is SFTPAttributes: + elif isinstance(item, SFTPAttributes): item._pack(msg) else: raise Exception('unknown type for %r type %r' % (item, type(item))) |