Перемещение файлов из одного каталога в другой с использованием Java - PullRequest
1 голос
/ 19 июля 2009

У меня проблемы с перемещением файлов в каталогах на Java. Проблема в том, что я не могу понять, почему программа ведет себя так, как она себя ведет. Ниже (небольшая) модификация моей настоящей программы.

Я пересекаю каталоги каталога. В каждом из этих пройденных каталогов Есть текстовые файлы, которые я хочу переместить в две подкаталоги пройденного каталога. Я создаю эти два каталога (trainingData и testData). Я хочу, чтобы 30 файлов были перемещены в каталог testData, а 60 - в каталог trainingData. Для этого я делаю две петли.

В приведенном ниже коде я поместил сначала цикл, перемещающий файлы в trainingData. И хорошая новость в том, что все эти 60 файлов действительно перемещены в trainingData. Однако второй цикл, похоже, ничего не делает - ни один из этих 30 оставшихся файлов не перемещается. Эти 30 файлов продолжают оставаться в исходном (пройденном) каталоге.

Более того, что-то очень странное в том, что когда я обмениваю два цикла - ставим один, перемещающий 30 файлов, на первое место, а другой после него, тогда 30 файлов правильно перемещаются в testData, однако 30 из 60 других файлов перемещаются в каталог trainingData, а остальные 30 файлов остаются в исходном (пройденном) каталоге.

Программа по-прежнему не выполняет то, что я хочу (только частично), однако меня беспокоит то, что я не понимаю, почему это различие (??), когда я обмениваюсь местами двух циклов. Код идентичен и должен работать одинаково, не так ли?

Спасибо, что потратили время на изучение кода, и при необходимости я готов предоставить больше кода и пояснений.

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);
         }
     }
 }

Ответы [ 2 ]

2 голосов
/ 19 июля 2009

Имейте в виду, что File.renameTo (dest) может (скорее всего, потерпит неудачу), если каталог назначения не находится в той же файловой системе.

В этом случае вам потребуется реализовать копию и удалить семантику;

1 голос
/ 19 июля 2009

Выполните второй цикл следующим образом:

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

Проблема в том, что в обоих циклах вы индексируете одинаковые array из File s. Когда вы физически перемещаете файл, он не удаляется из массива. Это просто остается там. Во втором цикле он пытается переместить файлы, которые уже были перемещены. Вот почему во втором цикле ваша индексная переменная должна начинаться с последнего значения в первом цикле.

Это также объясняет, почему при обмене обоими циклами только 30 файлов копируются из исходного каталога: первые 30 игнорируются, поскольку они уже были скопированы; остальные 30 копируются по назначению.

В качестве альтернативы, вы можете сделать еще один reviews = sortedRevDir.listFiles(); между двумя циклами, чтобы сделать циклы проще, но это немного расточительно с точки зрения производительности, поскольку это еще одна операция ввода-вывода, которая на самом деле не нужна.

...