且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何从FTP服务器中删除超过7天的Python脚本文件?

更新时间:2023-12-04 21:15:10

好的。假设您的FTP服务器支持 MLSD 命令,请使用以下代码创建一个模块(这是我用来将远程FTP站点与本地目录同步的脚本中的代码):

模块代码



 #for python≥2.6 
import sys,os,time,ftplib
导入集合
FTPDir = collections.namedtuple(FTPDir,name size mtime tree)
FTPFile = collections.namedtuple(FTPFile,名称大小mtime)

class FTPDirectory(object):
def __init __(self,path ='。'):
self.dirs = []
self .files = []
self.path = path

def getdata(self,ftpobj):
ftpobj.retrlines('MLSD',self.addline)

def addline(self,line):
data,_,name = line.partition(';')
fields = data.split(';')
for field在字段中:
field_name,_,field_value = field.partition('=')
if field_name ==类型':
target = self.dirs if field_value =='dir'else self.files
elif field_name in('sizd','size'):
size = int(field_value)
elif field_name =='modify':
mtime = time.mktime(time.strptime(field_value,%Y%m%d%H%M%S))
if target是self.files:
target.append(FTPFile(name,size,mtime))
else:
target.append(FTPDir(name,size,mtime,self .__ class __(os。 path.join(self.path,name))))

def walk(self):
在self.files中的ftpfile:
产生self.path,ftpfile
for ftpdir in self.dirs:
for path,ftpfile in ftpdir.tree.walk():
yield path,ftpfile

class FTPTree(FTPDirectory):
def getdata(self,ftpobj):
super(FTPTree,self).getdata(ftpobj)
for self.dirs中的dirname:
ftpobj.cwd(di rname.name)
dirname.tree.getdata(ftpobj)
ftpobj.cwd('..')



单个目录案例



如果您想处理目录的文件,您可以:

 导入ftplib,时间

quite_old = time.time() - 7 * 86400#七天

网站= ftplib.FTP(主机名,用户名,密码)
site.cwd(the_directory_to_work_on)#如果是'。',则可以跳过这一行
folder = FTPDirectory()
folder.getdata站点)#获取文件名
作为路径,ftpfile在folder.walk()中:
if ftpfile.mtime< quite_old:
site.delete(ftpfile.name)

这应该是你想要的。

一个目录和它的后代



现在,如果这应该递归地工作,你必须做在单一目录情况代码中进行了两处更改:

  folder = FTPTree()
$ $ b

  site.delete( os.path.join(path,ftpfile.name))



可能的警告



我使用的服务器在 STOR DELE 命令,所以 site.delete 的相对路径也起作用。如果您的FTP服务器需要无路径的文件名,您应该首先将 .cwd 添加到提供的路径中, .delete 平原 ftpfile.name 然后 .cwd 回到基础文件夹。

I would like to write a Python script which allows me to delete files from a FTP Server after they have reached a certain age. I prepared the scipt below but it throws the error message: WindowsError: [Error 3] The system cannot find the path specified: '/test123/*.*'

Do someone have an idea how to resolve this issue? Thank you in advance!

import os, time
from ftplib import FTP

ftp = FTP('127.0.0.1')
print "Automated FTP Maintainance"
print 'Logging in.'
ftp.login('admin', 'admin')

# This is the directory that we want to go to
path = 'test123'
print 'Changing to:' + path
ftp.cwd(path)
files = ftp.retrlines('LIST')
print 'List of Files:' + files 
#--everything works fine until here!...

#--The Logic which shall delete the files after the are 7 days old--
now = time.time()
for f in os.listdir(path):
  if os.stat(f).st_mtime < now - 7 * 86400:
    if os.path.isfile(f):
        os.remove(os.path.join(path, f))
except:
    exit ("Cannot delete files")

print 'Closing FTP connection'
ftp.close()

OK. Assuming your FTP server supports the MLSD command, make a module with the following code (this is code from a script I use to sync a remote FTP site with a local directory):

module code

# for python ≥ 2.6
import sys, os, time, ftplib
import collections
FTPDir= collections.namedtuple("FTPDir", "name size mtime tree")
FTPFile= collections.namedtuple("FTPFile", "name size mtime")

class FTPDirectory(object):
    def __init__(self, path='.'):
        self.dirs= []
        self.files= []
        self.path= path

    def getdata(self, ftpobj):
        ftpobj.retrlines('MLSD', self.addline)

    def addline(self, line):
        data, _, name= line.partition('; ')
        fields= data.split(';')
        for field in fields:
            field_name, _, field_value= field.partition('=')
            if field_name == 'type':
                target= self.dirs if field_value == 'dir' else self.files
            elif field_name in ('sizd', 'size'):
                size= int(field_value)
            elif field_name == 'modify':
                mtime= time.mktime(time.strptime(field_value, "%Y%m%d%H%M%S"))
        if target is self.files:
            target.append(FTPFile(name, size, mtime))
        else:
            target.append(FTPDir(name, size, mtime, self.__class__(os.path.join(self.path, name))))

    def walk(self):
        for ftpfile in self.files:
            yield self.path, ftpfile
        for ftpdir in self.dirs:
            for path, ftpfile in ftpdir.tree.walk():
                yield path, ftpfile

class FTPTree(FTPDirectory):
    def getdata(self, ftpobj):
        super(FTPTree, self).getdata(ftpobj)
        for dirname in self.dirs:
            ftpobj.cwd(dirname.name)
            dirname.tree.getdata(ftpobj)
            ftpobj.cwd('..')

single directory case

If you want to work on the files of a directory, you can:

import ftplib, time

quite_old= time.time() - 7*86400 # seven days

site= ftplib.FTP(hostname, username, password)
site.cwd(the_directory_to_work_on) # if it's '.', you can skip this line
folder= FTPDirectory()
folder.getdata(site) # get the filenames
for path, ftpfile in folder.walk():
    if ftpfile.mtime < quite_old:
        site.delete(ftpfile.name)

This should do what you want.

a directory and its descendants

Now, if this should work recursively, you'll have to do the following two changes in the code for "single directory case":

folder= FTPTree()

and

site.delete(os.path.join(path, ftpfile.name))

Possible caveat

The servers I've worked with didn't have any issues with relative paths in the STOR and DELE commands, so site.delete with a relative path worked too. If your FTP server requires pathless filenames, you should first .cwd to the path provided, .delete the plain ftpfile.name and then .cwd back to the base folder.