获取用pysftp迭代的文件和文件夹的属性Connection.walktree?

Obtaining attributes of files and folders iterated with pysftp Connection.walktree?

我正在尝试使用 pysftp 在目录下递归地列出文件及其修改时间。问题是,它显示文件不存在于所有文件,但不存在于目录。

这是我的代码:

class SftpOps:
    def __init__(self):
        config = ConfigManager()
        host = config.getSftpUrl()
        port = config.getSftpPort()
        user = config.getSftpUsername()
        password = config.getSftpPassword()
        self.source = config.getSourceDirRelativePath()

        cnopts = pysftp.CnOpts()
        cnopts.hostkeys.load('host_key')

        self.sftp = pysftp.Connection(
            host, port=port, username=user, password=password, cnopts=cnopts)

    def downloadSourceDir(self):
        print(self.sftp.listdir())
        self.sftp.walktree(self.source, self.fileModifiedTimeCheck,
                           self.dirModifiedTimeCheck, self.fileModifiedTimeCheck, recurse=True)
        self.sftp.close()

    def fileModifiedTimeCheck(self, filepath):
        filepath = os.path.join(self.source, filepath)
        try:
            for attr in self.sftp.listdir_attr(filepath):
                print(f"{filepath}: {attr.st_atime}")
        except FileNotFoundError as err:
            print(f"No file at: {filepath}, failed with err: {err}")
        except OSError as err:
            print("OS error: {0}".format(err))
        except:
            print("Unexpected error:", sys.exc_info()[0])
            raise

    def dirModifiedTimeCheck(self, filepath):
        filepath = os.path.join(self.source, filepath)
        try:
            for attr in self.sftp.listdir_attr(filepath):
                print(f"{filepath}: {attr.st_atime}")
            filepath = "tmp/"+filepath
        except FileNotFoundError:
            print(f"No dir at: {filepath}")
        except OSError as err:
            print("OS error: {0}".format(err))
        except:
            print("Unexpected error:", sys.exc_info()[0])
            raise


# class LogOps:
#     def __init__(self):


# class EmailOps:
#     def __init__(self):

print("=========================================")
test_obj = SftpOps()
test_obj.downloadSourceDir()
print("=========================================")

当我为具有以下结构的目录尝试此操作时

它给出的错误为:

=========================================
['.DS_Store', 'about-me.html', 'favicon.ico', 'index.html', 'test']
No file at: /Downloads/techtuft/.DS_Store, failed with err: [Errno 2] No such file
No file at: /Downloads/techtuft/about-me.html, failed with err: [Errno 2] No such file
No file at: /Downloads/techtuft/favicon.ico, failed with err: [Errno 2] No such file
No file at: /Downloads/techtuft/index.html, failed with err: [Errno 2] No such file
/Downloads/techtuft/test: 1569165379
No file at: /Downloads/techtuft/test/style.css, failed with err: [Errno 2] No such file
=========================================

请注意,它不显示目录 "test".

的错误

所以看起来 listdir_attr 方法显示目录中的当前条目,但不处理特殊条目,例如包含 ... 的路径。从文档中参考 here。这就是 test 文件夹未包含在您的错误消息中的原因。

但是您可以使用 lstat 方法来识别文件:

>>> for i in sftp.listdir():
...     lstatout=str(sftp.lstat(i)).split()[0]
...     if 'd' not in lstatout: #do something
... 

您不能对文件使用 Connection.listdir_attr

你应该使用 Connection.stat.

尽管那样效率很低。您最好复制 walktree 函数的实现并使其调用 Connection.listdir_attr 而不是 Connection.listdir。这样您就可以在对服务器的一次调用中获得目录中所有文件的时间戳,而不是低效地逐个文件地检索它们。

另见 Python SFTP download files older than x and delete networked storage