Auto deleting files older than given minutes on Windows
I have a folder on my PC in which I keep my temporary files, which I won't be needing after some time. I manually delete them from time to time. What is a way to automate this? I can think of deleting files whose last access time is greater than 20 minutes using Java, but then again, I would have to run it myself which still wouldn't be automation. I using using Windows and file system is NTFS.
Solution 1:
If you simply want to delete files after a given number of minutes with no advanced logic, the GNUWin32 build of the Linux "find" command is a simple option.
Setup
- Download the current binary (findutils-4.2.20-2-bin) and dependency (findutils-4.2.20-2-dep) .zip files to your PC and extract them as normal.
- Copy the items from the "bin" folder in Dependencies to the "bin" folder in Binaries. You can copy the "manifest" folder items as well but this is not strictly required.
- In the Binaries "bin" folder, rename find.exe to something else (e.g. gnu_find.exe). This prevents confusion with the built-in Windows "find" command.
- Feel free to rename/place the Binaries folder however you wish.
Use
Delete all files older than X minutes (e.g. 5 minutes) in a given directory (e.g. TempFiles)
gnu_find.exe "C:\Path\To\TempFiles" ! -mmin -5 -type f -delete
Note that the ! (negation) operator is important. Leaving this out will delete files under (less than) X minutes old.
To move items to the Windows Recycle Bin (rather than using -delete to remove them directly), please see the "Recycle Bin" section at the end of this answer.
Options
-
-name can be used to filter items. -name should always appear before -delete or it will have no effect e.g.
gnu_find.exe "C:\Path\To\TempFiles" ! -mmin -5 -type f -name "*text*" -delete
In the example above, -name matches any file with the sequence "text" anywhere in the file name (including extensions). Use an asterisk (*) for any portion where you want wildcard matching. Asterisks can appear more than once. If matching an exact name, you must include an extension on Windows.
-
-exec ex_command {} + allows the use of an external command e.g. "ex_command" when eligible items are found. This could be useful for running a separate process (such as a batch file or similar) when "find" matches items successfully. This option should be put at the end of the "find" options i.e.
gnu_find.exe "C:\Path\To\TempFiles" ! -mmin -5 -type f -delete -exec ex_command {} +
-
-delete is optional (as are all the options). You can leave it off if you want to preview what "find" will be working on (e.g. for testing or troubleshooting) or simply want a listing of files.
-
Be aware that if you are listing files for output, a UNIX forward slash will be placed between the directory name and the file name e.g.
C:\Path\To\TempFiles/filename.txt
Therefore, you may need to take appropriate steps to correct this later.
Other Options
If you need fancier options than the ones listed above, you may have to write your own script.
Features vary by language but, as an example, Python has time.time() (current time via the time module) as well as os.path.getctime() and os.path.getmtime() (Windows creation time and file modification times respectively via the os module). These all return floating points in seconds from an epoch time and make time comparison extremely easy.
As you mentioned Java, you may want to check out this StackOverflow question on Java NIO for similar features.
Automation
As mentioned in comments, Windows Task Scheduler can be used to run items periodically, including once ever X minutes. You could use it to run a single-line batch file with the GNUWin32 "find" command above.
You can set increments as small as 1 minute in the Trigger settings for the Windows 7 Task Scheduler. You must type in custom increments e.g. 1 minute manually in the "Repeat task every:" drop-down field, otherwise an item from the default increment list will be used.
Note that while Task Scheduler may be acceptable, one quirk is that it technically starts a task at a given time, then repeats it for 24 hours. This can lead to problems if the computer is not on when a task is set to run.
To help counter this, you must enable "Settings → Run task as soon as possible after a scheduled start is missed".
Other Automation Options
As a suggestion, a tool similar to the UNIX "cron" utility might be preferable. There are a number of better and worse emulations of it, but personally I prefer IntelliAdmin Cron Service v2.0.
IntelliAdmin Cron installs a simple service that runs listed tasks at specific intervals as long as the service is running. It will accept crontab files for scheduling but also has a GUI interface.
One thing to note is that the fields in the GUI interface still expect crontab style entries for specifying times to run. You may want to research this further but the format to run every X minutes is
*/X
with all other values set to "*". So if we wanted to run a command every minute, it would look like this in the interface:
Time Frames Other Than Minutes
Time frames other than minutes are of course supported as well e.g.
gnu_find.exe "C:\Path\To\TempFiles" -mtime +30 -type f -delete
can be used to -delete files with a modification time older than 30 days.
Recycle Bin
Unfortunately, -delete removes items directly and permanently. However, you can use scripts or third-party executables to send items to the Recycle Bin.
One answer to the Super User question linked above includes a link to a homebrew utility called binit. You can use this utility in conjunction with the GNUWin32 version of "find" to move items to the Recycle Bin with the -exec ex_command {} + option mentioned earlier e.g.
gnu_find.exe "C:\Path\To\TempFiles" ! -mmin -5 -type f -exec "C:\Path\To\binit.exe" {} +
Solution 2:
Use Powershell Script + Task Manager:
You can use the following command in powershell to crate the script (Change 30 to how many minutes you want or change Minutes to Hours or Days)
Get-ChildItem –Path "C:\path\to\folder" -Recurse | Where-Object {($_.LastWriteTime -lt (Get-Date).AddMinutes(-30))} | Remove-Item
Once you create the script, apply it to task scheduler.