Thomas Schroyen · Apr 11, 2019

How to sequentialy delete file from a folder

Hello gentlemen,

here is my question: I would like to delete files one by one (not all at a time because I need to check somethinkg to delete it or not) in a defined folder but how can I handle it?  I have used the extension :


But it only works when a file is moved in my folder... But I want to launch my program everyday (with a planifier) in the purpose to delete file that more that 2 months old. With "PassthroughService", it won't work since the the file is not moved so it won't go in my onProcessInput...

If you can offer me a solution, I'll take it :)
Here is a sample of my code:

Class citadelle.test.FileDeletingWithFilter Extends EnsLib.File.PassthroughService

Property DumpPath As %String(MAXLEN = 500);

Property TargetEmailSenderName As %String(MAXLEN = 128);

Property KeyOfLookUpTable As %String;

Parameter SETTINGS = "KeyOfLookUpTable:Basic, TargetEmailSenderName:Basic:selector?multiSelect=1&context={Ens.ContextSearch/ProductionItems?targets=1&productionName=@productionId}, DumpPath:Basic";

Method OnProcessInput(pInput As %Stream.Object, Output pOutput As %RegisteredObject) As %Status
    SET sc = $$$OK
    set ..Adapter.DeleteFromServer = ""    //Useful because we check ourselves if delete is needed
    set tTableName = "NameFolderDoNotDelete"
    SET directory = ""
    SET filePath = pInput.Attributes("Filename")
    $$$TRACE("Filepath: "_filePath)
    SET filename = $PIECE(filePath,"\",*)

    SET dumpPath = ..DumpPath    //Directory where to delete everything
    If ##class(Ens.Util.LookupTable).%ExistsTable(tTableName)'=1
    {    // send mail
        $$$TRACE(tTableName_".lut doesn't exist, mail sent to warn")
        SET msg = ##class(
        SET msg.To = "XXXXXX"
        SET msg.Subject = "Erreur,une table n'existe pas"
        SET msg.Body = "Bonjour,<br/> la LookUp table '"_tTableName_"' n'existe pas.<br/> Veuillez la créer. <br/>Bien à vous,<br/> FileDeletingWithFilter.cls"
        DO ..SendRequestAsync(..TargetEmailSenderName,msg)
        Set offset = $FIND(filePath,dumpPath) 
        If (offset > 0)
            SET directory = $EXTRACT(filePath, offset+1, *-$LENGTH(filename)-1) //+1 et -1 pour enlever les \
            $$$TRACE("Lists of directory that we cannot delete: "_directory)
        try {
            SET valueToCheck =  ^Ens.LookupTable(tTableName,..KeyOfLookUpTable)
        } catch (ex)
            s sc = ex.AsStatus()
            $$$TRACE("No values found in the lookup table")
            set valueToCheck = ""
        if sc '= $$$OK
            q sc
        SET isDeleteNeeded = 0 //default = do not delete
        if ($FIND($ZCONVERT(valueToCheck,"U"),$ZCONVERT(directory,"U")) = 0) { //the folder is NOT in the "we cannot delete" list of the folder
            // delete file that are more than 2 months old
            SET dateNow = $ZDATETIME($HOROLOG, 3, 1)        //2018-12-14 11:22:58
            Set fileStream=##class(%File).%New(filePath)
            set fileStreamTimestamp = fileStream.LastModifiedGet()
            set ecart = $system.SQL.DATEDIFF("mm",fileStreamTimestamp,dateNow)
            $$$TRACE("Gap: "_ecart_" months")
             if (ecart >= 2 ) { SET isDeleteNeeded = 1 }
         if (isDeleteNeeded){
            $$$TRACE("File " _ filePath _ " is now deleted")
            SET statusFile = ##class(%Library.File).Delete(filePath)
    QUIT sc



0 1,237
Discussion (6)3
Log in or sign up to continue

Hi Thomas

Can I clarify your question, what you are really looking to do is each day start a process that will delete files in a given directory that are older than some period of time?

If so I may be able to help there.


Hi Jenna,

I was interested in doing something that you are mentioning.  Do you have anything that could start me off?

Thank you.

Kind Regards,


I have a task that deletes txt files  older than x number of days:

Class PROD.Schedule.PurgeTxtFiles Extends %SYS.Task.Definition

Parameter TaskName = "Purge TXT Files";

Property Directory As %String;

Property Daystokeep As %Integer(VALUELIST = ",5,10,15,20,25,30,35,40,45,50,55,60") [ InitialExpression = "30" ];

Method OnTask() As %Status

Set tsc = ..PurgeSentFolder(..Directory,..Daystokeep,"txt")
Quit tsc

Method PurgeSentFolder(Directory As %String, DaysToKeep As %Integer, Extention As %String) As %Status
// Calculate the oldest date to keep files on or after
set BeforeThisDate = $zdt($h-DaysToKeep_",0",3)

// Gather the list of files in the specified directory
set rs=##class(%ResultSet).%New("%File:FileSet")
Set ext = "*."_Extention
do rs.Execute(Directory,ext,"DateModified")

// Step through the files in DateModified order
while rs.Next() {
set DateModified=rs.Get("DateModified")
if BeforeThisDate]DateModified {
// Delete the file
set Name=rs.Get("Name")
do ##class(%File).Delete(Name)
// Stop when we get to files with last modified dates on or after our delete date
if DateModified]BeforeThisDate 
set tSC = 1
quit tSC


Hopefully you can make this work for your needs smiley


This is great thanks, it's exactly what I was looking for.  Thank you so much.

Kind Regards,


Not sure if that's right, but maybe you're asking for this? You can do whatever you want on each iteration, including delete the obsolete files.


Heres something I did on a Windows system at one point to purge files in a directory that were older than a given time frame

ClassMethod PurgeFiles(Path As %String, OlderThan As %Integer)
    set Date=$zd($h-OlderThan)
    set cmd="forfiles /P "_Path_" /D -"_Date_" /C ""cmd /c del @path"""
    set sc=$zf(-1,cmd)

I'm pretty sure there is also ways to do this using something in %File or one of those classes also. I will poke around for an example there as well, but this should get you started.