3

我想通过 sftp 下载一些超过 2 小时的文件。然后我想从网站上删除它们。我可以将以下代码用于 sftp,但在远程机器上处理对象给我带来了问题。下面的代码在“timestamp = os.stat”行失败我相信这是一个操作系统模块问题?

import paramiko, sys, os,time

host = 'ftp address'
port = 22
transport = paramiko.Transport((host, port))
password = "pass"                   #hard-coded
username = "user"                   #hard-coded
transport.connect(username = username, password = password)


sftp = paramiko.SFTPClient.from_transport(transport)
print 'SFTP Client initiated'

remotepath = "/remote folder/"
localpath = '/local folder/' 

for file in sftp.listdir('.'):
    fullpath   = os.path.join('.',file) 
    timestamp  = os.stat(fullpath).st_ctime # get timestamp of file
    createtime = datetime.datetime.fromtimestamp(timestamp)
    now = datetime.datetime.now()
    delta = now -createtime
    if delta.hours > 2:
        sftp.get(file,localpath) 
        sftp.remove(file)

sftp.close()
transport.close()   
4

2 回答 2

2

虽然 OP 的自我接受的答案几乎可以工作,但它的效率非常低,因为它涉及每个文件到服务器的往返。虽然实际上代码已经拥有所有需要的数据,但它只是通过使用pysftp.Connection.listdir包装器将其丢弃,而不是pysftp.Connection.listdir_attr直接使用。

for entry in sftp.listdir_attr(remotepath):
    timestamp = entry.st_mtime
    createtime = datetime.datetime.fromtimestamp(timestamp)
    now = datetime.datetime.now()
    delta = now - createtime
    if delta.hours > 2:
        filepath = remotepath + '/' + entry.filename
        sftp.get(filepath, os.path.join(localpath, entry.filename)) 
        sftp.remove(filepath)

Connection.listdir在内部检索与 相同的数据Connection.listdir_attr。他们最终都打电话给 Paramiko SFTPClient.listdir_attr。但Connection.listdir只返回文件名,丢弃所有其他文件属性。另请参阅如何通过 Paramiko 获取目录中所有 SFTP 文件的大小

虽然请注意 pysftp 似乎已经死了。考虑直接使用 Paramiko。它具有几乎相同的 API,因此上面的代码将按原样工作。另请参阅pysftp 与 Paramiko


此外,不应os.path.join在 SFTP 路径上使用。SFTP 始终使用正斜杠,而os.path.join使用本地路径语法,因此在 Windows 上,它将使用反斜杠并且代码将失败

并且目标路径也pysftp.Connection.get需要一个文件名,而不仅仅是一个路径(这里os.path.join应该使用)

于 2019-05-24T08:36:02.600 回答
1

获取远程计算机上文件的时间戳然后将其与现在进行比较所需的位如下。由非程序员(我)一起破解,但它有效。

timestamp  = sftp.stat(fullpath).st_atime  # get timestamp of file in epoch seconds
createtime = datetime.datetime.now()
now        = time.mktime(createtime.timetuple())
datetime.timedelta = now - timestamp

if datetime.timedelta> x:
    do something
于 2012-09-20T12:07:19.647 回答