β

[NIO.2] 编写一个文件拷贝应用

Aptusource.orgAptusource.org 159 阅读

拷贝目录树的时候,需要为文件和目录递归调用 Files.copy() 方法。在开始编写代码之前,要注意以下几点:

在拷贝目录中的文件之前,必须先拷贝目录本身。不管目录中是否有文件,拷贝目录后的结果都将是空目录。这个任务必须在 preVisitDirectory() 中完成。

下面的代码将演示将 C:\rafaelnadal 子目录树拷贝到  C:\rafaelnadal_copy 中:

import java.nio.file.FileSystemLoopException; 
import java.nio.file.attribute.FileTime; 
import java.io.IOException; 
import java.nio.file.FileVisitOption; 
import java.nio.file.FileVisitResult; 
import java.nio.file.FileVisitor; 
import java.nio.file.Files; 
import java.nio.file.Path; 
import java.nio.file.Paths; 
import java.nio.file.attribute.BasicFileAttributes; 
import java.util.EnumSet; 
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; 
import static java.nio.file.StandardCopyOption.COPY_ATTRIBUTES; 
 
class CopyTree implements FileVisitor { 
 
   private final Path copyFrom; 
   private final Path copyTo; 
 
   public CopyTree(Path copyFrom, Path copyTo) { 
        this.copyFrom = copyFrom; 
        this.copyTo = copyTo; 
    } 
 
   static void copySubTree(Path copyFrom, Path copyTo) throws IOException { 
        try { 
            Files.copy(copyFrom, copyTo, REPLACE_EXISTING, COPY_ATTRIBUTES); 
        } catch (IOException e) { 
            System.err.println("Unable to copy " + copyFrom + " [" + e + "]"); 
        } 
 
    } 
 
   @Override 
   public FileVisitResult postVisitDirectory(Object dir, IOException exc)  
                                                                     throws IOException { 
        if (exc == null) { 
            Path newdir = copyTo.resolve(copyFrom.relativize((Path) dir)); 
            try { 
                FileTime time = Files.getLastModifiedTime((Path) dir); 
                Files.setLastModifiedTime(newdir, time); 
            } catch (IOException e) { 
                System.err.println("Unable to copy all attributes to: " + newdir+" ["+e+ "]"); 
            } 
        } else { 
            throw exc; 
        } 
 
        return FileVisitResult.CONTINUE; 
    } 
 
    @Override 
    public FileVisitResult preVisitDirectory(Object dir, BasicFileAttributes attrs) 
        System.out.println("Copy directory: " + (Path) dir); 
        Path newdir = copyTo.resolve(copyFrom.relativize((Path) dir)); 
        try { 
            Files.copy((Path) dir, newdir, REPLACE_EXISTING, COPY_ATTRIBUTES); 
        } catch (IOException e) { 
            System.err.println("Unable to create " + newdir + " [" + e + "]"); 
            return FileVisitResult.SKIP_SUBTREE; 
        } 
 
        return FileVisitResult.CONTINUE; 
    } 
 
    @Override 
    public FileVisitResult visitFile(Object file, BasicFileAttributes attrs)  
                                                                      throws IOException { 
        System.out.println("Copy file: " + (Path) file); 
        copySubTree((Path) file, copyTo.resolve(copyFrom.relativize((Path) file))); 
        return FileVisitResult.CONTINUE; 
    } 
 
    @Override 
    public FileVisitResult visitFileFailed(Object file, IOException exc)  
                                                                     throws IOException { 
        if (exc instanceof FileSystemLoopException) { 
            System.err.println("Cycle was detected: " + (Path) file); 
        } else { 
            System.err.println("Error occurred, unable to copy:" +(Path) file+" ["+ exc + 
"]"); 
        } 
 
        return FileVisitResult.CONTINUE; 
    } 
} 
 
class Main { 
 
    public static void main(String[] args) throws IOException { 
 
        Path copyFrom = Paths.get("C:/rafaelnadal"); 
        Path copyTo = Paths.get("C:/rafaelnadal_copy"); 
 
        CopyTree walk = new CopyTree(copyFrom, copyTo); 
        EnumSet opts = EnumSet.of(FileVisitOption.FOLLOW_LINKS); 
 
        Files.walkFileTree(copyFrom, opts, Integer.MAX_VALUE, walk); 
    } 
}

运行了上面的代码后,你将发现 C:\rafaelnadal_copy 和 C:\rafaelnadal 将会有完全一样的目录树和属性。

作者:Aptusource.orgAptusource.org
最好的 Java 技术博客
原文地址:[NIO.2] 编写一个文件拷贝应用, 感谢原作者分享。

发表评论