Article
· Jan 23 2m de lecture

Fichiers temporaires et singletons : Nettoyage après utilisation

J'ai rencontré à plusieurs reprises un cas où j'ai besoin d'utiliser un fichier/dossier temporaire et de le supprimer ultérieurement.

La solution la plus naturelle consiste alors à suivre les recommandations de "Robust Error Handling and Cleanup in ObjectScript" avec un bloc try/catch/pseudo-finally ou un objet enregistré pour gérer le nettoyage dans le destructeur. %Stream.File* possède également une propriété RemoveOnClose que vous pouvez définir, mais avec précaution, car vous pourriez supprimer accidentellement un fichier important. De plus, cette propriété est réinitialisée par les appels à %Save(), vous devrez donc la remettre à 1 après chaque utilisation.

Il existe cependant un cas particulier : supposons que vous ayez besoin que le fichier temporaire subsiste dans la pile d'exécution. Par exemple :

ClassMethod MethodA()
{
    Do ..MethodB(.filename)
    // Do something else with the filename
}

ClassMethod MethodB(Output filename)
{
    // Create a temp file and set filename to the file's name
    Set filename = ##class(%Library.File).TempFilename()
    
    //... and probably do some other stuff
}

Vous pourriez toujours manipuler des objets %Stream.File* avec RemoveOnClose défini sur 1, mais nous nous intéressons ici uniquement aux fichiers temporaires.

C'est là qu'intervient le concept de « Singleton ». IPM propose une implémentation de base dans %IPM.General.Singleton, que vous pouvez étendre pour répondre à différents cas d'utilisation. Le comportement général et le modèle d'utilisation sont les suivants :

  • À un niveau de pile supérieur, appelez %Get() sur cette classe pour obtenir l'unique instance, également accessible par des appels à %Get() à des niveaux de pile inférieurs.
  • Lorsque l'objet sort de la portée au niveau de pile le plus élevé qui l'utilise, le code de nettoyage est exécuté.

Cette méthode est plus performante qu'une variable `%` car il n'est pas nécessaire de vérifier sa définition, et elle survit également aux appels NEW sans argument aux niveaux de pile inférieurs grâce à une astuce de manipulation d'objets plus profonde.

Concernant les fichiers temporaires, IPM propose également un singleton pour la gestion des fichiers temporaires. Appliquée à ce problème, la solution est la suivante :

ClassMethod MethodA()
{
    Set tempFileManager = ##class(%IPM.Utils.TempFileManager).%Get()
    Do ..MethodB(.filename)
    // Do something else with the filename
    // The temp file is cleaned up automatically when tempFileManager goes out of scope
}

ClassMethod MethodB(Output filename)
{
    Set tempFileManager = ##class(%IPM.Utils.TempFileManager).%Get()
    // Create a temp file and set filename to the file's name
    Set filename = tempFileManager.GetTempFileName(".md")
    
    //... and probably do some other stuff
}
Discussion (0)1
Connectez-vous ou inscrivez-vous pour continuer