【问题标题】:Moving files from one directory to another with Java NIO使用 Java NIO 将文件从一个目录移动到另一个目录
【发布时间】:2014-04-16 21:16:31
【问题描述】:

我正在使用 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目录中。

【问题讨论】:

    标签: java io directory nio


    【解决方案1】:

    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"
    

    【讨论】:

    【解决方案2】:

    最好不要回到 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();
        }
    

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      • java.nio 比 java.io 包具有更好的文件处理能力。当您处理名称中包含特殊字符的文件时,我遇到了不良行为。更好的做事方式是@Andrew 的回应。
      【解决方案4】:

      试试这个代码:

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

      【讨论】:

        【解决方案5】:

        继续@Andrew's answer

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

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

        DirectoryStream 用于遍历目录中的条目。目录流允许方便地使用 for-each 结构来迭代目录。所以我们得到了src 的绝对路径,我们使用resolve 方法来解析dst 的绝对路径。

        更多信息请参考DirectoryStream

        【讨论】:

          猜你喜欢
          • 2017-07-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-09-26
          • 1970-01-01
          • 2017-06-09
          • 1970-01-01
          相关资源
          最近更新 更多