使用Java将文件从一个目录移动到另一个目录

时间:2009-07-18 21:08:58

标签: java file for-loop move

我在Java中的目录中移动文件时遇到问题。问题是我无法理解为什么程序的行为方式。下面是我的真实程序的(轻微)修改。

我遍历目录的目录。在每个遍历的目录中 有文本文件,我想将其移动到遍历目录的两个子目录中。我创建了这两个目录(trainingDatatestData)。我希望将30个文件移动到testData目录中,将其中60个移到trainingData目录中。为此我制作了两个for循环。

在下面的代码中,我首先将循环文件移到trainingData。好消息是所有这60个文件都被转移到了trainingData。然而,第二个循环似乎没有做任何事情 - 没有移动这30个剩余文件中的任何文件。这30个文件继续保留在原始(遍历)目录中。

此外,非常奇怪的是,当我交换两个循环时 - 将一个移动30个文件放在第一个位置,另一个放在它之后,然后将30个文件正确移动到testData,但是,其他60个文件中的30个被移动到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 个答案:

答案 0 :(得分:2)

请记住,如果目标目录不在同一文件系统上,File.renameTo(dest)可能(可能会)失败。

在这种情况下,您需要实现副本并删除语义;

答案 1 :(得分:1)

按如下方式进行第二次循环:

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

问题是,在两个循环中,您索引array Filereviews = sortedRevDir.listFiles();。当您物理移动文件时,它不会从阵列中删除。它只是呆在那里。在第二个循环中,它尝试移动已移动的文件。所以这就是为什么在第二个循环中,你的索引变量必须从第一个循环中的最终值继续。

它还解释了为什么当你交换两个循环时,只从原始目录复制30个文件:前30个被忽略,因为它们已被复制;其余30个按预期复制。

或者,您可以在两个循环之间执行另一个{{1}}以使循环更简单,但这在性能方面有点浪费,因为它是另一个不必要的IO操作。