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

9

我正在使用NIO库,但当我试图将文件从一个目录移动到另一个目录时,出现了奇怪的错误。

String yearNow = new SimpleDateFormat("yyyy").format(
    Calendar.getInstance().getTime());

try {
     DirectoryStream<Path> curYearStream = 
       Files.newDirectoryStream(sourceDir, "{" + yearNow + "*}"); 
       //Glob for current year

     Path newDir = Paths.get(sourceDir + "//" + yearNow);

     if (!Files.exists(newDir) || !Files.isDirectory(newDir)) {
         Files.createDirectory(newDir); 
         //create 2014 directory if it doesn't exist
     }
}

遍历以 "2014" 开头的元素,并将它们移动到新目录(newDir,也称为2014)中。
for (Path p : curYearStream) {
    System.out.println(p); //it prints out exactly the files that I need to move
    Files.move(p, newDir); //java.nio.file.FileAlreadyExistsException
}

我遇到了java.nio.file.FileAlreadyExistsException的问题,因为我的文件夹(2014)已经存在。实际上,我想要做的是将所有以“2014”开头的文件移动到2014目录中。

5个回答

17

最好不要返回到java.io.File并使用NIO代替:

    Path sourceDir = Paths.get("c:\\source");
    Path destinationDir = Paths.get("c:\\dest");

    try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(sourceDir)) {
        for (Path path : directoryStream) {
            System.out.println("copying " + path.toString());
            Path d2 = destinationDir.resolve(path.getFileName());
            System.out.println("destination File=" + d2);
            Files.move(path, d2, REPLACE_EXISTING);
        }
    } catch (IOException ex) {
        ex.printStackTrace();
    }

14

Files.move 不等同于 mv 命令。它不会检测目标位置是否为目录并将文件移动到其中。

你需要逐个构建完整的目标路径。如果你想要把 /src/a.txt 复制到 /dest/2014/,目标路径应该是 /dest/2014/a.txt

你可以尝试像下面这样做:

File srcFile = new File("/src/a.txt");
File destDir = new File("/dest/2014");
Path src = srcFile.toPath();
Path dest = new File(destDir, srcFile.getName()).toPath(); // "/dest/2014/a.txt"

你可以使用Paths.get()来创建src和dest,然后使用Files.move(),并设置REPLACE_EXISTING选项,这样会更好。 - nrobey

3

继续使用@Andrew的答案

如果我们仅使用Files.move(src, dst, StandardCopyOption.REPLACE_EXISTING);,那么它将删除源目录,因为我们只提供了目录路径而不是特定文件的绝对路径。因此,当操作完成时,它也将删除源目录。

假设源路径为/opt/src,其中包含csv文件,目标路径为/opt/dst,我想将所有文件从src移动到dst,并且我正在使用Files.move(src, dst, StandardCopyOption.REPLACE_EXISTING);,那么它将移动所有文件到dst,但在移动所有文件后,它将删除src目录,因为我们没有为srcdst每个文件提供绝对路径。我们应该像/opt/src/foo.csv/opt/dst/foo.csv这样提供src路径和dst路径,然后它就不会删除源目录。

DirectoryStream 用于遍历目录中的条目。目录流允许方便地使用 for-each 结构来遍历目录。因此,我们获取 src 的绝对路径,并使用 resolve 方法来解析 dst 的绝对路径。

请参阅 DirectoryStream 获取更多信息。


0
尝试这段代码:
public class App
{
    public void moveFromSourceToDestination(String sourceName,String destinationName)
    {
        File mydir = new File(sourceName);
        if (mydir.isDirectory())
        {
            File[] myContent = mydir.listFiles();
            for(int i = 0; i < myContent.length; i++)
            {
                File file1 = myContent[i];
                file1.renameTo(new File(destinationName+file1.getName()));
            }
        }
    }

    public static void main(String [] args)
    {
        App app = new App();
        String sourceName = "C:\\Users\\SourceFolder";
        String destinationName = "C:\\Users\\DestinationFolder\\";
        app.moveFromSourceToDestination(sourceName,destinationName);
    }
}

-1

使用java.io.File,就像这样简单:

File srcFile = new File(srcDir, fileName);
srcFile.renameTo(new File(destDir, "a.txt"));

java.nio比java.io包具有更好的文件处理能力。我曾经遇到过在处理名称中带有特殊字符的文件时出现的不良行为。更好的做法是采用@Andrew的回答。 - Victor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接