add visitor

This commit is contained in:
Looly 2020-11-16 18:02:27 +08:00
parent ea3060cddf
commit 583b7cbe47
6 changed files with 146 additions and 26 deletions

View File

@ -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

View File

@ -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,25 +156,61 @@ 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 !");
Path destPath = isDirectory(dest) ? dest.resolve(src.getFileName()) : dest;
final Path targetPath = isDirectory(target) ? target.resolve(src.getFileName()) : target;
try {
return Files.copy(src, destPath, options);
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);
}
/**
* 拷贝目录下的所有文件或目录到目标目录中
*
* @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 {
Files.walkFileTree(src, new CopyVisitor(src, target));
} catch (IOException e) {
throw new IORuntimeException(e);
}
return target;
}
/**
* 判断是否为目录如果file为null则返回false<br>
* 此方法不会追踪到软链对应的真实地址即软链被当作文件

View File

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

View File

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

View File

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

View File

@ -19,6 +19,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(){