1

I am trying to delete a particular folder in Java and I am using Apache Commons class to do the job. If there is any better option please let me know as well.

import org.apache.commons.io.FileUtils;

FileUtils.deleteDirectory(new File(destination));

Now what I need to do is - I need to find all the directories within this folder /opt/hello/world which is X days old (here X can be 30 days) and delete all those directory one by one. These directories can contain files as well so once I delete directory, files will also get deleted . I was looking into the API and I saw AgeFilter class so I started using like this:

import java.io.File;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.AgeFileFilter;

private static final int DAYS_OLD = 30;

public void deleteFiles(File file) {
    long purgeTime = System.currentTimeMillis() - (DAYS_OLD * 24L * 60L * 60L * 1000L);
    Iterator<File> filesToDelete = FileUtils.iterateFiles(file, new AgeFileFilter(purgeTime), TRUE);
    for (File aFile : filesToDelete) {
        aFile.delete();
    }
}

But I am getting this error in for loop. What wrong I am doing?

Can only iterate over an array or an instance of java.lang.Iterable

Update:-

long purgeTime = System.currentTimeMillis() - (DAYS_OLD * 24L * 60L * 60L * 1000L);
AgeFileFilter filter = new AgeFileFilter(purgeTime);

File path = new File("/opt/hello/world");
File[] oldFolders = FileFilterUtils.filter(filter, path);

for (File folder : oldFolders) {
    FileUtils.deleteDirectory(folder);
}
user1950349
  • 4,738
  • 19
  • 67
  • 119

2 Answers2

1

You could use FileFilterUtils.filter(IOFileFilter, File...) instead, which will return a array of Files matching your filter.

I'd also recommend using just about anything else then basic time arithmetic, for example Java 8 has a new Time API, you could use a Joda-Time or even Calendar at a stretch, they will account for some of the anomalies surrounding date/time computation

As an example...

LocalDate today = LocalDate.now();
LocalDate eailer = today.minusDays(30);

Date threshold = Date.from(eailer.atStartOfDay(ZoneId.systemDefault()).toInstant());
AgeFileFilter filter = new AgeFileFilter(threshold);

File path = new File("...");
File[] oldFolders = FileFilterUtils.filter(
                FileFilterUtils.directoryFileFilter(), 
                FileFilterUtils.filter(
                                filter, 
                                path.listFiles()));

for (File folder : oldFolders) {
    System.out.println(folder);
}

But which you would use (Iterable or array) comes down to what you need

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • Thanks for your suggestion. I am still on Java 7. Also Is there any way I can just find the directories which are X days old and then delete those folder instead of looking up all the files in each directory and then deleting them one by one. I need to find all the directories within this folder `/opt/hello/world` which is X days old. – user1950349 Sep 09 '15 at 01:55
  • Doesn't Apache's `FileUtils` have a `deleteDirectory` method? [`FileUtils.deleteDirectory`](https://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/FileUtils.html#deleteDirectory(java.io.File)), you could also use `FileUtils.deleteQuietly` which won't throw any exceptions if it can't delete one or more files/sub directories – MadProgrammer Sep 09 '15 at 01:58
  • You could also compound `FileFilterUtils` to filter by age and directory. `FileFilterUtils.filter(ageFilter, FileFilterUtils.filter(FileFilterUtils.directoryFileFilter(), path))` as an example – MadProgrammer Sep 09 '15 at 02:00
  • In your example this line `File path = new File("...");` is specifically this `File path = new File("/opt/hello/world");` right? I have updated the question with full details of how the code will look like. Let me know if I am doing anything wrong. – user1950349 Sep 09 '15 at 02:01
  • Yes, path is the "root" directory which you want to list ;) – MadProgrammer Sep 09 '15 at 02:02
  • Ok got it. Then what is the difference between your solution that you have in the answer as compared to compound one you mentioned? – user1950349 Sep 09 '15 at 02:04
  • I've updated the answer to demonstrate using a directory/age filter to filter the contents of the directory. The returned result will be a list of directories which are at least your threashold age – MadProgrammer Sep 09 '15 at 02:12
0

You're facing the same problem of this guy

To safely remove from a collection while iterating over it you should use an Iterator.

**And call the next item before delete

Mark answered in a complete way. Take a look here

List<File> files= ....
Iterator<File> i = files.iterator();
while (i.hasNext()) {
   File s = i.next(); // must be called before you can call i.remove()
   // Do something
   i.remove();
}
Community
  • 1
  • 1
Renan Ceratto
  • 130
  • 2
  • 12
  • No, the OP isn't trying to remove elements from the iterator, they are trying to loop through the iterator and delete the referenced file, which would leave the iterator intake but the file will (potentionally) no longer exist – MadProgrammer Sep 09 '15 at 02:02