Question
· 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 :

EnsLib.File.PassthroughService

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
    $$$TRACE(dumpPath)
    If ##class(Ens.Util.LookupTable).%ExistsTable(tTableName)'=1
    {    // send mail
        $$$TRACE(tTableName_".lut doesn't exist, mail sent to warn")
        SET msg = ##class(citadelle.email.MessageEmail).%New()
        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)
    }
    else
    {
        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)
            $$$TRACE(valueToCheck)
        } 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
}
}

Thanks,

Thomas

Discussion (6)1
Log in or sign up to continue

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

Hi-

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.

Jen