How do I detect the latest files created in a directory?

Hello everyone,
In a Timer
How to detect the last file created in a directory thanks to its creation date?
Thank you.

Maybe use CreationDateTime?

I’m not sure because it allows you to change the creation date.

Or keep track of the files in the folder and if you detect a new one consider it as latest file created?

If you have a Einhugur plugin pack use FileSystemWatcher FileSystemWatcher

3 Likes

As @AlbertoD says, use a file monitor (requires a plugin or delcares with Xojo). I used the following tutorial to add such a thing to one of my SwiftUI apps.

The macOS URL class ( plugin or declares in Xojo) has properties for when a file was added to a directory, regardless of its actual creation date.

2 Likes

Of course you can also change the timestamp, but what is more important is that you can read the timestamp. So you only have to look for files that have a created timestamp that matches the time from the last check to now. And from those, pick the one with the highest CreatedDateTime Stamp.

I would like to offer you one of my beginner-friendly and infamous quick & dirty solutions. I hope this is of some help to you. :slight_smile:

Var f As FolderItem = SpecialFolder.Desktop
If theFiles = Nil Then theFiles = New Dictionary // This Dictionary is a property of our Class/Window/...

For Each file As FolderItem In f.Children
  
  If Not file.IsFolder Then // We ignore Folders...
    
    Try
      
      If theFiles.HasKey(file.Name) Then // A file with this name is already known
        
        If theFiles.Value(file.Name) <> file.CreationDateTime.SQLDateTime + file.ModificationDateTime.SQLDateTime Then // Created and/or Modified differ from what we knew about a file with this name!
          
          theFiles.Remove(file.Name) // Remove the outdated file with this name (beware! can cause issues with FileSystems which allow same name multiple times in one folder!)
          theFiles.Value(file.Name) = file.CreationDateTime.SQLDateTime + file.ModificationDateTime.SQLDateTime // Ad a new file with this name and timestamps
          
        End If
        
      Else // This filename is new
        
        theFiles.Value(file.Name) = file.CreationDateTime.SQLDateTime + file.ModificationDateTime.SQLDateTime
        
      End If
      
    Catch err As KeyNotFoundException
      // Handle the issue here...
    Catch err As OutOfBoundsException
      // Handle the issue here...
    End Try
    
  End If
  
Next
2 Likes

Thank you all for your solutions, which I treasure, but I’ve just done something simpler
In fact, the files created in the directory have the hour and minutes at the beginning of their names.
I compare the current time (in string form) with the first 4 letters of each file name, and display it.
The only problem is that the times of the files created don’t have the 0 in front of them, e.g. 9h01 = 901 and not 0901!

I guess you don’t control those filenames?

Why do you remove the key/value pair before adding the same key? Setting the value replaces an existing entry, so the “remove” call is unneeded.

1 Like

Updated, based on @Arnaud_N’s comment. Thank you :slight_smile:

Var f As FolderItem = SpecialFolder.Desktop // Replace this with the correct path
If theFiles = Nil Then theFiles = New Dictionary // This Dictionary is a property of our Class/Window/...

For Each file As FolderItem In f.Children
  If Not file.IsFolder Then // We ignore Folders...
    Try
      If theFiles.HasKey(file.Name) Then // A file with this name is already known
        If theFiles.Value(file.Name) <> file.CreationDateTime.SQLDateTime + file.ModificationDateTime.SQLDateTime Then // Created and/or Modified differ from what we knew about a file with this name!
          theFiles.Value(file.Name) = file.CreationDateTime.SQLDateTime + file.ModificationDateTime.SQLDateTime // Replace the outdated file with this one (beware! can cause issues with FileSystems which allow same name multiple times in one folder!)
        End If
      Else // This filename is new
        theFiles.Value(file.Name) = file.CreationDateTime.SQLDateTime + file.ModificationDateTime.SQLDateTime
      End If
    Catch err As KeyNotFoundException
    Catch err As OutOfBoundsException
    End Try
  End If
Next

In a previous attempt i was experimenting with a FolderItem Array. :wink:

I’m not sure if this is really simpler. As you have already experienced, it can cause additional issues. And what’s more important is, that it can break in the future if the naming scheme changes. :slight_smile:

2 Likes

Since I currently have a few minutes, I would like to add something about the future-proofing of your application. Since you have only recently registered in the forum, I assume that you are still relatively new to working with Xojo. And in case you are also quite new to application development, here is something from my own experience.


I develop software for an internet and telephone service provider. Since I never know how long I will be able to do this in this company, I pay as much attention as I can to making my solutions future-proof.

This means that I try, where possible, to not make conditions dependent on user input or external sources. I also try to make as much as possible variable, so that changes are possible without having to update the application.
This goes so far that at some points, my program loads database queries or API requests from a database instead of storing them in the program. This means that not only contents such as email or letter templates are variable, but the structure of the underlying databases or APIs may even change here and there.

I “just” need to make sure that my program still works even when I am no longer working.

BTW: Sorry if my assumptions are wrong. I don’t want to be arrogant. Thanks. :slight_smile:

1 Like

That’s right!! and I never have the 0 in front!!, here’s my code

For Each uFile As WebUploadedFile In files
Try
If uFile.file <> Nil Then
uploadedPicture = Picture.Open(uFile.File)
Else
uploadedPicture = Picture.FromData(uFile.data)
End If
Var d As DateTime = DateTime.Now
Var s As String = Session.identifier

// Save the file to disk
savePicture = RepDiaporama.Child(d.Hour.ToString + d.Minute.ToString + d.Second.ToString + s.LeftBytes(5) + uFile.Name )
uFile.Save(savePicture)
ImageViewer1.Picture=Picture.Open(uFile.File)

Catch err As IOException

Exit For

End Try
Next

How about:

savePicture = RepDiaporama.Child(d.ToString(DateTime.FormatStyles.None, DateTime.FormatStyles.Medium).ReplaceAll(":","") + s.LeftBytes(5) + uFile.Name )

or

savePicture = RepDiaporama.Child(Format(d.Hour,"00") + Format(d.Minute,"00") + Format(d.Second,"00") + s.LeftBytes(5) + uFile.Name )

or

savePicture = RepDiaporama.Child(d.SQLDateTime.Right(8).ReplaceAll(":","") + s.LeftBytes(5) + uFile.Name )

:smiley:

If you put the Try before the For…Next Loop, you don’t need to put the Exit For into the Catch Section. And since you use the DateTime and the Session Object only once, you don’t need to create local Variables for them. :wink:

Try
  For Each uFile As WebUploadedFile In files
    
    If uFile.file <> Nil Then
      uploadedPicture = Picture.Open(uFile.File)
    Else
      uploadedPicture = Picture.FromData(uFile.data)
    End If
    // Save the file to disk
    savePicture = RepDiaporama.Child(DateTime.Now.SQLDateTime.Right(8).ReplaceAll(":","") + Session.identifier.LeftBytes(5) + uFile.Name )
    uFile.Save(savePicture)
    ImageViewer1.Picture=Picture.Open(uFile.File)
  Next
Catch err As IOException
End Try
1 Like

Thank you very much for your help, now it works very well :+1:

1 Like

Thank you very much for your feedback and I take note of it and yes indeed I even have a little distant experience (more than 10 years ago!) VB6, PHP I am rediscovering development, so I am making errors in beginner and I want to learn, learn, unfortunately there are not many tutorials in French and even training for beginners. Fortunately there are people like you who give without counting :pray:

1 Like