user42155
user42155

Reputation: 49665

Moving files from one directory to another, using Java

I have problems with moving files in directories in Java. The problem is that I cannot understand why the program behaves the way it behaves. Below is a (slight) modification of my real program.

I traverse directories of a directory. In each of these traversed directories there are text files, which I want to move into two subdirectories of the traversed directory. I create these two directories (trainingData and testData). I want 30 of the files to be moved into the testData directory and 60 of them in the trainingData directory. For this purpose I make two for loops.

In the code below, I have put first the loop moving the files into trainingData. And the good news is that all these 60 files really are moved into trainingData. However, the second loop seems not to make anything - no file of any of these 30 remaining files is moved. These 30 files continue to stay in the original (traversed) directory.

Moreover, something very strange is that when I exchange the two loops - put the one moving the 30 files on the first place, and the other one after it, then the 30 files are correctly moved into testData, however, 30 of the other 60 files are moved into the trainingData directory and the rest 30 files stay in the original (traversed) directory.

The program still does not do what I want (only partly), however, what bothers me is that I don't understand why is this difference(??) when I exchange the places of the two loops. The code is identical, and should work the same, shouldn't it?

Thanks for the time of looking into the code, and if necessary I am willing to provide more code and explanations.

File[] reviews = null;
for(File sortedRevDir : sortedRevDirs) {
     reviews = sortedRevDir.listFiles();
     int numFiles = 90;
     int numTwoThirds = 60;
     int numOneThirds = numFiles - numTwoThirds;     

     String trainingDir = sortedRevDir.getAbsolutePath() + "/trainingData";
     File trDir = new File(trainingDir);
     trDir.mkdir();
     String testDir = sortedRevDir.getAbsolutePath() + "/testData";
     File tsDir = new File(testDir);
     tsDir.mkdir();

     for(int i = 0; i < numTwoThirds; i++) {
         File review = reviews[i];
         if(!review.isDirectory()) {
              File reviewCopied = new File(trDir + "/" + review.getName());
              review.renameTo(reviewCopied);
         } 
     }
     for(int j = 0; j < numOneThird; j++) {
         File review = reviews[j];
         if(!review.isDirectory()) {
          File reviewCopied = new File(tsDir + "/" + review.getName());
          review.renameTo(reviewCopied);
         }
     }
 }

Upvotes: 1

Views: 11821

Answers (2)

jottos
jottos

Reputation: 20358

Keep in mind that File.renameTo(dest) may (likely will) fail if your destination directory is not on the same filesystem.

In that case you'll need to implement a copy and delete semantic;

Upvotes: 2

jqno
jqno

Reputation: 15520

Do the second loop as follows:

for(int j = numTwoThirds; j < numTwoThirds + numOneThird; j++) {

The problem is that, in both loops, you index the same array of Files. When you physically move the file, it doesn't get removed from the array. It simply stays there. In the second loop, it tries to move files that were already moved. So that's why, in the second loop, your index variable has to continue from the final value in the first loop.

It also explains why, when you exchange both loops, only 30 files are copied from the original directory: the first 30 are ignored because they were already copied; the remaining 30 are copied as intended.

Alternatively, you could do another reviews = sortedRevDir.listFiles(); between the two loops to keep the loops simpler, but that's a bit wasteful performance-wise, since it's another IO operation that's not really necessary.

Upvotes: 1

Related Questions