Browse Source

add visitor

Looly 5 years ago
parent
commit
583b7cbe47

+ 3 - 1
CHANGELOG.md

@@ -3,9 +3,11 @@
 
 -------------------------------------------------------------------------------------------------------------
 
-# 5.5.1 (2020-11-15)
+# 5.5.1 (2020-11-16)
 
 ### 新特性
+* 【core   】     增加CopyVisitor和DelVisitor
+
 ### Bug修复
 * 【core   】     修复在Linux下FileUtil.move失败问题(issue#I254Y3@Gitee)
 

+ 46 - 25
hutool-core/src/main/java/cn/hutool/core/io/file/PathUtil.java

@@ -2,6 +2,8 @@ package cn.hutool.core.io.file;
 
 import cn.hutool.core.io.IORuntimeException;
 import cn.hutool.core.io.IoUtil;
+import cn.hutool.core.io.file.visitor.CopyVisitor;
+import cn.hutool.core.io.file.visitor.DelVisitor;
 import cn.hutool.core.lang.Assert;
 import cn.hutool.core.util.CharsetUtil;
 
@@ -128,24 +130,7 @@ public class PathUtil {
 
 		try {
 			if (isDirectory(path)) {
-				Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
-
-					@Override
-					public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
-						Files.delete(file);
-						return FileVisitResult.CONTINUE;
-					}
-
-					@Override
-					public FileVisitResult postVisitDirectory(Path dir, IOException e) throws IOException {
-						if (e == null) {
-							Files.delete(dir);
-							return FileVisitResult.CONTINUE;
-						} else {
-							throw e;
-						}
-					}
-				});
+				Files.walkFileTree(path, DelVisitor.INSTANCE);
 			} else {
 				Files.delete(path);
 			}
@@ -158,7 +143,7 @@ public class PathUtil {
 	/**
 	 * 通过JDK7+的 {@link Files#copy(Path, Path, CopyOption...)} 方法拷贝文件
 	 *
-	 * @param src     源文件路径
+	 * @param src     源文件路径,如果为目录只在目标中创建新目录
 	 * @param dest    目标文件或目录,如果为目录使用与源文件相同的文件名
 	 * @param options {@link StandardCopyOption}
 	 * @return Path
@@ -171,23 +156,59 @@ public class PathUtil {
 	/**
 	 * 通过JDK7+的 {@link Files#copy(Path, Path, CopyOption...)} 方法拷贝文件
 	 *
-	 * @param src     源文件路径
-	 * @param dest    目标文件或目录,如果为目录使用与源文件相同的文件名
+	 * @param src     源文件路径,如果为目录只在目标中创建新目录
+	 * @param target    目标文件或目录,如果为目录使用与源文件相同的文件名
 	 * @param options {@link StandardCopyOption}
 	 * @return Path
 	 * @throws IORuntimeException IO异常
 	 * @since 5.4.1
 	 */
-	public static Path copyFile(Path src, Path dest, CopyOption... options) throws IORuntimeException {
+	public static Path copyFile(Path src, Path target, CopyOption... options) throws IORuntimeException {
 		Assert.notNull(src, "Source File is null !");
-		Assert.notNull(dest, "Destination File or directiory is null !");
+		Assert.notNull(target, "Destination File or directiory is null !");
+
+		final Path targetPath = isDirectory(target) ? target.resolve(src.getFileName()) : target;
+		try {
+			return Files.copy(src, targetPath, options);
+		} catch (IOException e) {
+			throw new IORuntimeException(e);
+		}
+	}
+
+	/**
+	 * 拷贝文件或目录
+	 *
+	 * @param src     源文件路径,如果为目录只在目标中创建新目录
+	 * @param target    目标文件或目录,如果为目录使用与源文件相同的文件名
+	 * @param options {@link StandardCopyOption}
+	 * @return Path
+	 * @throws IORuntimeException IO异常
+	 * @since 5.5.1
+	 */
+	public static Path copy(Path src, Path target, CopyOption... options) throws IORuntimeException {
+		if(isFile(src, false)){
+			return copyFile(src, target, options);
+		}
+		return copyContent(src, target.resolve(src.getFileName()), options);
+	}
 
-		Path destPath = isDirectory(dest) ? dest.resolve(src.getFileName()) : dest;
+	/**
+	 * 拷贝目录下的所有文件或目录到目标目录中
+	 *
+	 * @param src     源文件路径,如果为目录只在目标中创建新目录
+	 * @param target    目标文件或目录,如果为目录使用与源文件相同的文件名
+	 * @param options {@link StandardCopyOption}
+	 * @return Path
+	 * @throws IORuntimeException IO异常
+	 * @since 5.5.1
+	 */
+	public static Path copyContent(Path src, Path target, CopyOption... options) throws IORuntimeException {
 		try {
-			return Files.copy(src, destPath, options);
+			Files.walkFileTree(src, new CopyVisitor(src, target));
 		} catch (IOException e) {
 			throw new IORuntimeException(e);
 		}
+		return target;
 	}
 
 	/**

+ 46 - 0
hutool-core/src/main/java/cn/hutool/core/io/file/visitor/CopyVisitor.java

@@ -0,0 +1,46 @@
+package cn.hutool.core.io.file.visitor;
+
+import java.io.IOException;
+import java.nio.file.FileAlreadyExistsException;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+
+/**
+ * 文件拷贝的FileVisitor实现,用于递归遍历拷贝目录
+ *
+ * @author looly
+ * @since 5.5.1
+ */
+public class CopyVisitor extends SimpleFileVisitor<Path> {
+
+	final Path source;
+	final Path target;
+
+	public CopyVisitor(Path source, Path target) {
+		this.source = source;
+		this.target = target;
+	}
+
+	@Override
+	public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
+			throws IOException {
+		final Path targetDir = target.resolve(source.relativize(dir));
+		try {
+			Files.copy(dir, targetDir);
+		} catch (FileAlreadyExistsException e) {
+			if (!Files.isDirectory(targetDir))
+				throw e;
+		}
+		return FileVisitResult.CONTINUE;
+	}
+
+	@Override
+	public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+			throws IOException {
+		Files.copy(file, target.resolve(source.relativize(file)));
+		return FileVisitResult.CONTINUE;
+	}
+}

+ 35 - 0
hutool-core/src/main/java/cn/hutool/core/io/file/visitor/DelVisitor.java

@@ -0,0 +1,35 @@
+package cn.hutool.core.io.file.visitor;
+
+import java.io.IOException;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+
+/**
+ * 删除操作的FileVisitor实现,用于递归遍历删除文件夹
+ *
+ * @author looly
+ * @since 5.5.1
+ */
+public class DelVisitor extends SimpleFileVisitor<Path> {
+
+	public static DelVisitor INSTANCE = new DelVisitor();
+
+	@Override
+	public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
+		Files.delete(file);
+		return FileVisitResult.CONTINUE;
+	}
+
+	@Override
+	public FileVisitResult postVisitDirectory(Path dir, IOException e) throws IOException {
+		if (e == null) {
+			Files.delete(dir);
+			return FileVisitResult.CONTINUE;
+		} else {
+			throw e;
+		}
+	}
+}

+ 7 - 0
hutool-core/src/main/java/cn/hutool/core/io/file/visitor/package-info.java

@@ -0,0 +1,7 @@
+/**
+ * FileVisitor功能性实现,包括递归删除、拷贝等
+ * 
+ * @author looly
+ *
+ */
+package cn.hutool.core.io.file.visitor;

+ 9 - 0
hutool-core/src/test/java/cn/hutool/core/io/file/PathUtilTest.java

@@ -21,6 +21,15 @@ public class PathUtilTest {
 
 	@Test
 	@Ignore
+	public void copyTest(){
+		PathUtil.copy(
+				Paths.get("d:/Red2_LYY"),
+				Paths.get("d:/test/")
+		);
+	}
+
+	@Test
+	@Ignore
 	public void moveTest(){
 		PathUtil.move(Paths.get("d:/lombok.jar"), Paths.get("d:/test/"), false);
 	}