Vaclav
Vaclav

Reputation: 57

Deleting files (weird extension)

I have a problem when I want to delete files in a repository using Java. What I want to do is to check if a repository exists, if it does I want to delete all the files it contains. Here is my code :

File f = new File(this.pathToFolder); 

if (f.exists() && f.isDirectory()) {
  for (int i = 0; i < f.listFiles().length ; i++) {    
    f.listFiles()[i].delete(); 
  }
}     
else {
  f.mkdir();
}

But the thing is that sometimes it doesn't delete the files. My guess is that it is because the files I want to delete have a weird title such as : 1.20.36579.55485875 They are files that I download and I can't choose their names.

Now I tried something like that :

File f = new File(this.pathToFolder); 

if (f.exists() && f.isDirectory()) {
  int i = 0;
  while (f.listFiles().length != 0) {
    boolean remove  = f.listFiles()[i].delete(); 
    System.out.println(remove);
  }
} 
else {
  f.mkdir();
} 

In the console I get a lot of "false" (about 15) and then eventually a true.

I don't understand why it is acting like this. Maybe some of you will have an idea.

Thank you, Vaclav

Upvotes: 3

Views: 92

Answers (3)

yaccob
yaccob

Reputation: 1333

The problem of your first approach (the for loop) was already addressed.

Regarding you second approach I'm guessing a bit. I would assume (didn't verify it) that deletion is not yet finished when you come to your next iteration. So listFiles()[0] may still be the same as in the previous iteration.

If your code prints more output lines (true of false) than you have files in the directory I'd assume that I'm guessing right.

Anyway the solution suggested by Joakim Danielson ...

for (File file : f.listFiles()) {
    file.delete();
}

... addresses both issues by calling listFiles() only once and then iterating over the resulting array.

You could achieve the same (in a less elegant way) by amending your code slightly:

File f = new File(this.pathToFolder); 

if (f.exists() && f.isDirectory()) {
  File[] files = f.listFiles(); // calling listFiles only once ...
  for (int i = 0; i < files.length ; i++) { // ... and then operating on the resulting array
    files[i].delete(); 
  }
}     
else {
  f.mkdir();
}

... not tested - I hope I made no mistake.

Btw the javadoc for listFiles says:

There is no guarantee that the name strings in the resulting array will appear in any specific order; they are not, in particular, guaranteed to appear in alphabetical order.

That's another good reason to not call listFiles() more than once while processing a directory.

Upvotes: 1

Vadim Fedorenko
Vadim Fedorenko

Reputation: 2561

Try to iterate over the files using an iterator

for (Iterator<File> it = Arrays.stream(f.listFiles()).iterator(); it.hasNext();) {
    File file = it.next();  
    file.delete();
}

Upvotes: 1

Joakim Danielson
Joakim Danielson

Reputation: 51882

The problem with your code is that you are modifying the listFiles() array while deleting files so the size of the array is shrinking for each time through the loop.

Try this

for (File file : f.listFiles()) {
    file.delete();
}

Upvotes: 2

Related Questions