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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1148571/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 15:22:16  来源:igfitidea点击:

Moving files from one directory to another, using Java

javafilefor-loopmove

提问by user42155

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.

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

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 (trainingDataand testData). I want 30 of the files to be moved into the testDatadirectory and 60 of them in the trainingDatadirectory. For this purpose I make two for loops.

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

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.

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

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 trainingDatadirectory and the rest 30 files stay in the original (traversed) directory.

此外,非常奇怪的是,当我交换两个循环时 - 将一个移动 30 个文件的一个放在第一位,另一个在它之后,然后 30 个文件被正确地移动到 30 个文件中testData,但是,其他 60 个文件中的 30 个移动到trainingData目录中,其余 30 个文件保留在原始(遍历)目录中。

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

采纳答案by jqno

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 arrayof 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.

问题是,在这两个循环,就指数相同arrayFile秒。当您物理移动文件时,它不会从阵列中删除。它只是停留在那里。在第二个循环中,它尝试移动已经移动的文件。这就是为什么在第二个循环中,您的索引变量必须从第一个循环中的最终值继续。

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.

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

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.

或者,您可以reviews = sortedRevDir.listFiles();在两个循环之间执行另一个循环以保持循环更简单,但这在性能方面有点浪费,因为它是另一个并非真正必要的 IO 操作。

回答by jottos

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

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

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

在这种情况下,您需要实现复制和删除语义;