更新时间: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
andDELE
commands, sosite.delete
with a relative path worked too. If your FTP server requires pathless filenames, you should first.cwd
to thepath
provided,.delete
the plainftpfile.name
and then.cwd
back to the base folder.