java nio: walkFileTree实现文件夹复制移动删除

从java 1.7开始,java提供了java.noi.file.Files类用于更方便的实现文件/文件夹操作。
在Files中提供了丰富的静态方法用于文件操作,Files也提供了文件移动和复制操作(Files.move,Files.copy),但是对于不为的空文件夹,不能调用Files.move,Files.copy实现文件夹下所有文件的复制和移动。
根据Files.move,Files.copy的说明,如果要移动/复制包含子目录的文件夹,需要用Files.walkFileTree方法配合Files.move,Files.copy来实现。以下是实现代码:

NioFileUtil.java

package net.gdface.iadb;

import java.io.IOException;
import java.nio.file.CopyOption;
import java.nio.file.DirectoryNotEmptyException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.StandardCopyOption;
import java.nio.file.attribute.BasicFileAttributes;

/** * 使用于NIO实现文件夹的复制/移动,删除
* 需要java 1.7以上版本支持 * @author guyadong * */
public class NioFileUtil { /** * 复制文件夹 * @param source * @param target * @param options * @throws IOException * @see {@link #operateDir(boolean, Path, Path, CopyOption...)} */ public static void copyDir(Path source, Path target, CopyOption... options) throws IOException{ operateDir(false, source, target, options); } /** * 移动文件夹 * @param source * @param target * @param options * @throws IOException * @see {@link #operateDir(boolean, Path, Path, CopyOption...)} */ public static void moveDir(Path source, Path target, CopyOption... options) throws IOException{ operateDir(true, source, target, options); } /** * 复制/移动文件夹 * @param move 操作标记,为true时移动文件夹,否则为复制 * @param source 要复制/移动的源文件夹 * @param target 源文件夹要复制/移动到的目标文件夹 * @param options 文件复制选项 * @throws IOException * @see Files#move(Path, Path, CopyOption...) * @see Files#copy(Path, Path, CopyOption...) * @see Files#walkFileTree(Path, java.nio.file.FileVisitor) */ public static void operateDir(boolean move,Path source, Path target, CopyOption... options) throws IOException{ if(null==source||!Files.isDirectory(source)) throw new IllegalArgumentException("source must be directory"); Path dest = target.resolve(source.getFileName()); // 如果相同则返回 if(Files.exists(dest)&&Files.isSameFile(source, dest))return; // 目标文件夹不能是源文件夹的子文件夹 // isSub方法实现参见另一篇博客 http://blog.csdn.net/10km/article/details/54425614 if(isSub(source,dest)) throw new IllegalArgumentException("dest must not be sub directory of source"); boolean clear=true; for(CopyOption option:options) if(StandardCopyOption.REPLACE_EXISTING==option){ clear=false; break; } // 如果指定了REPLACE_EXISTING选项则不清除目标文件夹 if(clear) deleteIfExists(dest); Files.walkFileTree(source, new SimpleFileVisitor() { @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { // 在目标文件夹中创建dir对应的子文件夹 Path subDir = 0==dir.compareTo(source)?dest:dest.resolve(dir.subpath(source.getNameCount(), dir.getNameCount())); Files.createDirectories(subDir); return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { if(move) Files.move(file, dest.resolve(file.subpath(source.getNameCount(), file.getNameCount())),options); else Files.copy(file, dest.resolve(file.subpath(source.getNameCount(), file.getNameCount())),options); return FileVisitResult.CONTINUE; } @Override public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { // 移动操作时删除源文件夹 if(move) Files.delete(dir); return super.postVisitDirectory(dir, exc); } }); } /** * 强制删除文件/文件夹(含不为空的文件夹)
* @param dir * @throws IOException * @see Files#deleteIfExists(Path) * @see Files#walkFileTree(Path, java.nio.file.FileVisitor) */
public static void deleteIfExists(Path dir) throws IOException { try { Files.deleteIfExists(dir); } catch (DirectoryNotEmptyException e) { Files.walkFileTree(dir, new SimpleFileVisitor() { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { Files.delete(file); return FileVisitResult.CONTINUE; } @Override public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { Files.delete(dir); return super.postVisitDirectory(dir, exc); } }); } } }

测试代码

    public void testCopy() throws IOException{
        Path start = Paths.get("d:\\tmp\\storeroot\\origin");
        Path target = Paths.get("E:\\tmp\\storeroot");
        NioFileUtil.copyDir(start, target);
    }

关于Files.walkFileTree方法的使用说明,参见这篇博客《walkFileTree、FileVisitor(遍历文件/目录)》,说得很详细了

你可能感兴趣的:(java)