This commit is contained in:
Looly 2023-03-31 13:19:11 +08:00
parent 9ad764c05e
commit f79dd096e2
2 changed files with 40 additions and 7 deletions

View File

@ -15,6 +15,7 @@ package cn.hutool.core.io.file;
import cn.hutool.core.io.IORuntimeException; import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.file.visitor.MoveVisitor; import cn.hutool.core.io.file.visitor.MoveVisitor;
import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.Assert;
import cn.hutool.core.text.StrUtil;
import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.ObjUtil;
import java.io.IOException; import java.io.IOException;
@ -82,27 +83,33 @@ public class PathMover {
* <li>如果src为文件target为不存在的路径则重命名源文件到目标指定的文件如move("/a/b", "/c/d"), d不存在则b变成d</li> * <li>如果src为文件target为不存在的路径则重命名源文件到目标指定的文件如move("/a/b", "/c/d"), d不存在则b变成d</li>
* <li>如果src为目录target为文件抛出{@link IllegalArgumentException}</li> * <li>如果src为目录target为文件抛出{@link IllegalArgumentException}</li>
* <li>如果src为目录target为目录则将源目录及其内容移动到目标路径目录中如move("/a/b", "/c/d")结果为"/c/d/b"</li> * <li>如果src为目录target为目录则将源目录及其内容移动到目标路径目录中如move("/a/b", "/c/d")结果为"/c/d/b"</li>
* <li>如果src为目录target为其子目录抛出{@link IllegalArgumentException}</li>
* <li>如果src为目录target为不存在的路径则重命名src到target如move("/a/b", "/c/d")结果为"/c/d/"相当于b重命名为d</li> * <li>如果src为目录target为不存在的路径则重命名src到target如move("/a/b", "/c/d")结果为"/c/d/"相当于b重命名为d</li>
* </ul> * </ul>
* *
* @return 目标文件Path * @return 目标文件Path
* @throws IllegalArgumentException src为目录target为其子目录抛出此异常
*/ */
public Path move() { public Path move() throws IllegalArgumentException{
final Path src = this.src; final Path src = this.src;
Path target = this.target; Path target = this.target;
final CopyOption[] options = this.options; final CopyOption[] options = this.options;
if (PathUtil.isSub(src, target)) {
if(Files.exists(target) && PathUtil.equals(src, target)){
// issue#2845当用户传入目标路径与源路径一致时直接返回否则会导致删除风险
return target;
}
// 当用户将文件夹拷贝到其子文件夹时报错
throw new IllegalArgumentException(StrUtil.format("Target [{}] is sub path of src [{}]!", target, src));
}
if (PathUtil.isDirectory(target)) { if (PathUtil.isDirectory(target)) {
// 创建子路径的情况1是目标是目录需要移动到目录下2是目标不能存在自动创建目录 // 创建子路径的情况1是目标是目录需要移动到目录下2是目标不能存在自动创建目录
target = target.resolve(src.getFileName()); target = target.resolve(src.getFileName());
} }
// issue#2893 target 不存在导致NoSuchFileException
if (Files.exists(target) && PathUtil.equals(src, target)) {
// issue#2845当用户传入目标路径与源路径一致时直接返回否则会导致删除风险
return target;
}
// 自动创建目标的父目录 // 自动创建目标的父目录
PathUtil.mkParentDirs(target); PathUtil.mkParentDirs(target);
try { try {

View File

@ -69,6 +69,22 @@ public class FileUtilTest {
FileUtil.move(FileUtil.file("d:/test/a"), FileUtil.file("d:/test/b"), false); FileUtil.move(FileUtil.file("d:/test/a"), FileUtil.file("d:/test/b"), false);
} }
@Test
@Disabled
public void renameToSubTest() {
Assertions.assertThrows(IllegalArgumentException.class, ()->{
// 移动到子目录报错
FileUtil.move(FileUtil.file("d:/test/a"), FileUtil.file("d:/test/a/c"), false);
});
}
@Test
@Disabled
public void renameSameTest() {
// 目标和源相同不处理
FileUtil.move(FileUtil.file("d:/test/a"), FileUtil.file("d:/test/a"), false);
}
@Test @Test
public void copyTest() { public void copyTest() {
final File srcFile = FileUtil.file("hutool.jpg"); final File srcFile = FileUtil.file("hutool.jpg");
@ -80,6 +96,16 @@ public class FileUtilTest {
Assertions.assertEquals(srcFile.length(), destFile.length()); Assertions.assertEquals(srcFile.length(), destFile.length());
} }
@Test
@Disabled
public void copySameTest() {
final File srcFile = FileUtil.file("d:/test/a");
final File destFile = FileUtil.file("d:/test/");
// 拷贝到当前目录不做处理
FileUtil.copy(srcFile, destFile, true);
}
@Test @Test
@Disabled @Disabled
public void copyDirTest() { public void copyDirTest() {