mirror of
https://gitee.com/dromara/hutool.git
synced 2025-04-24 18:04:54 +08:00
fixcode
This commit is contained in:
parent
7713db1730
commit
fb49d79f8b
@ -23,7 +23,7 @@ public class PathMover {
|
||||
* @param src 源文件或目录
|
||||
* @param target 目标文件或目录
|
||||
* @param isOverride 是否覆盖目标文件
|
||||
* @return {@link PathMover}
|
||||
* @return {@code PathMover}
|
||||
*/
|
||||
public static PathMover of(final Path src, final Path target, final boolean isOverride) {
|
||||
return of(src, target, isOverride ? new CopyOption[]{StandardCopyOption.REPLACE_EXISTING} : new CopyOption[]{});
|
||||
@ -35,7 +35,7 @@ public class PathMover {
|
||||
* @param src 源文件或目录
|
||||
* @param target 目标文件或目录
|
||||
* @param options 移动参数
|
||||
* @return {@link PathMover}
|
||||
* @return {@code PathMover}
|
||||
*/
|
||||
public static PathMover of(final Path src, final Path target, final CopyOption[] options) {
|
||||
return new PathMover(src, target, options);
|
||||
@ -48,25 +48,30 @@ public class PathMover {
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param src 源文件或目录
|
||||
* @param src 源文件或目录,不能为{@code null}且必须存在
|
||||
* @param target 目标文件或目录
|
||||
* @param options 移动参数
|
||||
*/
|
||||
public PathMover(final Path src, final Path target, final CopyOption[] options) {
|
||||
this.src = Assert.notNull(src, "Src path must be not null !");
|
||||
Assert.notNull(target, "Src path must be not null !");
|
||||
if(false == PathUtil.exists(src, false)){
|
||||
throw new IllegalArgumentException("Src path is not exist!");
|
||||
}
|
||||
this.src = src;
|
||||
this.target = Assert.notNull(target, "Target path must be not null !");
|
||||
this.options = options;
|
||||
this.options = ObjUtil.defaultIfNull(options, new CopyOption[]{});;
|
||||
}
|
||||
|
||||
/**
|
||||
* 移动文件或目录到目标中,例如:
|
||||
* <ul>
|
||||
* <li>如果src和target为同一文件或目录,直接返回target。</li>
|
||||
* <li>如果src为文件,target为目录,则移动到目标目录下,存在同名文件则按照是否覆盖参数执行。</li>
|
||||
* <li>如果src为文件,target为文件,则按照是否覆盖参数执行。</li>
|
||||
* <li>如果src为文件,target为不存在的路径,则重命名源文件到目标指定的文件,如moveContent("/a/b", "/c/d"), d不存在,则b变成d。</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为不存在的路径,则重命名src到target,如move("/a/b", "/c/d"),结果为"/c/d/",相当于b重命名为d</li>
|
||||
* </ul>
|
||||
*
|
||||
* @return 目标文件Path
|
||||
@ -74,9 +79,9 @@ public class PathMover {
|
||||
public Path move() {
|
||||
final Path src = this.src;
|
||||
Path target = this.target;
|
||||
final CopyOption[] options = ObjUtil.defaultIfNull(this.options, new CopyOption[]{});
|
||||
final CopyOption[] options = this.options;
|
||||
|
||||
if (false == PathUtil.exists(target, false) || PathUtil.isDirectory(target)) {
|
||||
if (PathUtil.isDirectory(target)) {
|
||||
// 创建子路径的情况,1是目标是目录,需要移动到目录下,2是目标不能存在,自动创建目录
|
||||
target = target.resolve(src.getFileName());
|
||||
}
|
||||
@ -98,13 +103,9 @@ public class PathMover {
|
||||
throw new IORuntimeException(e);
|
||||
}
|
||||
// 移动失败,可能是跨分区移动导致的,采用递归移动方式
|
||||
try {
|
||||
Files.walkFileTree(src, new MoveVisitor(src, target, options));
|
||||
// 移动后空目录没有删除,
|
||||
PathUtil.del(src);
|
||||
} catch (final IOException e2) {
|
||||
throw new IORuntimeException(e2);
|
||||
}
|
||||
walkMove(src, target, options);
|
||||
// 移动后删除空目录
|
||||
PathUtil.del(src);
|
||||
return target;
|
||||
}
|
||||
}
|
||||
@ -124,25 +125,43 @@ public class PathMover {
|
||||
*/
|
||||
public Path moveContent() {
|
||||
final Path src = this.src;
|
||||
if (PathUtil.isNotDirectory(target, false)) {
|
||||
// 文件移动调用move方法
|
||||
return move();
|
||||
}
|
||||
|
||||
final Path target = this.target;
|
||||
final CopyOption[] options = ObjUtil.defaultIfNull(this.options, new CopyOption[]{});
|
||||
if (PathUtil.isNotDirectory(target, false)) {
|
||||
// 目标不能为文件
|
||||
throw new IllegalArgumentException("Can not move dir content to a file");
|
||||
}
|
||||
|
||||
// issue#2893 target 不存在导致NoSuchFileException
|
||||
if (PathUtil.equals(src, target)) {
|
||||
// issue#2845,当用户传入目标路径与源路径一致时,直接返回,否则会导致删除风险。
|
||||
return target;
|
||||
}
|
||||
|
||||
final CopyOption[] options = this.options;
|
||||
|
||||
// 移动失败,可能是跨分区移动导致的,采用递归移动方式
|
||||
walkMove(src, target, options);
|
||||
return target;
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归移动
|
||||
*
|
||||
* @param src 源目录
|
||||
* @param target 目标目录
|
||||
* @param options 移动参数
|
||||
*/
|
||||
private static void walkMove(final Path src, final Path target, final CopyOption... options) {
|
||||
try {
|
||||
if (false == PathUtil.isDirectory(src)) {
|
||||
// 文件移动到目标目录或文件
|
||||
return Files.move(src, target, options);
|
||||
}
|
||||
|
||||
if (false == PathUtil.isDirectory(target)) {
|
||||
throw new IllegalArgumentException("Can not move dir content to a file");
|
||||
}
|
||||
|
||||
// 移动源目录下的内容而不删除目录
|
||||
Files.walkFileTree(src, new MoveVisitor(src, target, options));
|
||||
} catch (final IOException e) {
|
||||
throw new IORuntimeException(e);
|
||||
}
|
||||
return target;
|
||||
}
|
||||
}
|
||||
|
@ -252,6 +252,22 @@ public class PathUtil {
|
||||
return isDirectory(path, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否为非目录
|
||||
* <ul>
|
||||
* <li>如果path为{@code null},返回{@code false}</li>
|
||||
* <li>如果path不存在,返回{@code false}</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param path {@link Path}
|
||||
* @param isFollowLinks 是否追踪到软链对应的真实地址
|
||||
* @return 如果为目录true
|
||||
* @since 3.1.0
|
||||
*/
|
||||
public static boolean isNotDirectory(final Path path, final boolean isFollowLinks) {
|
||||
return exists(path, isFollowLinks) && false == isDirectory(path, isFollowLinks);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否为目录,如果file为null,则返回false
|
||||
*
|
||||
@ -438,6 +454,7 @@ public class PathUtil {
|
||||
*
|
||||
* <pre>
|
||||
* FileUtil.rename(file, "aaa.jpg", false) xx/xx.png =》xx/aaa.jpg
|
||||
* FileUtil.rename(dir, "dir2", false) xx/xx/ =》xx/dir2/
|
||||
* </pre>
|
||||
*
|
||||
* @param path 被修改的文件
|
||||
@ -453,12 +470,13 @@ public class PathUtil {
|
||||
/**
|
||||
* 移动文件或目录到目标中,例如:
|
||||
* <ul>
|
||||
* <li>如果src和target为同一文件或目录,直接返回target。</li>
|
||||
* <li>如果src为文件,target为目录,则移动到目标目录下,存在同名文件则按照是否覆盖参数执行。</li>
|
||||
* <li>如果src为文件,target为文件,则按照是否覆盖参数执行。</li>
|
||||
* <li>如果src为文件,target为不存在的路径,则重命名源文件到目标指定的文件,如moveContent("/a/b", "/c/d"), d不存在,则b变成d。</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为不存在的路径,则重命名src到target,如move("/a/b", "/c/d"),结果为"/c/d/",相当于b重命名为d</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param src 源文件或目录路径
|
||||
@ -539,12 +557,15 @@ public class PathUtil {
|
||||
/**
|
||||
* 判断文件或目录是否存在
|
||||
*
|
||||
* @param path 文件
|
||||
* @param path 文件,{@code null}返回{@code false}
|
||||
* @param isFollowLinks 是否跟踪软链(快捷方式)
|
||||
* @return 是否存在
|
||||
* @since 5.5.3
|
||||
*/
|
||||
public static boolean exists(final Path path, final boolean isFollowLinks) {
|
||||
if (null == path) {
|
||||
return false;
|
||||
}
|
||||
final LinkOption[] options = isFollowLinks ? new LinkOption[0] : new LinkOption[]{LinkOption.NOFOLLOW_LINKS};
|
||||
return Files.exists(path, options);
|
||||
}
|
||||
|
@ -21,6 +21,16 @@ public class IssueI666HBTest {
|
||||
FileUtil.move(FileUtil.file("d:/test/dir1"), FileUtil.file("d:/test/dir2"), false);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void moveContentDirToDirTest() {
|
||||
// 目录内容移动到目录
|
||||
// 移动内容,不移除目录本身
|
||||
PathUtil.moveContent(
|
||||
FileUtil.file("d:/test/dir1").toPath(),
|
||||
FileUtil.file("d:/test/dir2").toPath(), false);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void moveFileToDirTest() {
|
||||
@ -29,6 +39,16 @@ public class IssueI666HBTest {
|
||||
FileUtil.move(FileUtil.file("d:/test/dir1/test1.txt"), FileUtil.file("d:/test/dir2"), false);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void moveContentFileToDirTest() {
|
||||
// 文件移动到目录
|
||||
// 会将test1.txt移动到dir2下,变成dir2/test1.txt
|
||||
PathUtil.moveContent(
|
||||
FileUtil.file("d:/test/dir1/test1.txt").toPath(),
|
||||
FileUtil.file("d:/test/dir2").toPath(), false);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void moveDirToDirNotExistTest() {
|
||||
@ -37,11 +57,31 @@ public class IssueI666HBTest {
|
||||
FileUtil.move(FileUtil.file("d:/test/dir1"), FileUtil.file("d:/test/dir3"), false);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void moveContentDirToDirNotExistTest() {
|
||||
// 目录移动到目标,dir3不存在
|
||||
// 会将目录dir1内容移动到dir3,但是dir1目录不删除
|
||||
PathUtil.moveContent(
|
||||
FileUtil.file("d:/test/dir1").toPath(),
|
||||
FileUtil.file("d:/test/dir3").toPath(), false);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void moveFileToTargetNotExistTest() {
|
||||
// 目录移动到目录,将整个目录移动
|
||||
// 文件移动到不存在的路径
|
||||
// 会将test1.txt重命名为test2
|
||||
FileUtil.move(FileUtil.file("d:/test/dir1/test1.txt"), FileUtil.file("d:/test/test2"), false);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void moveContentFileToTargetNotExistTest() {
|
||||
// 目录移动到目录,将整个目录移动
|
||||
// 会将test1.txt重命名为test2
|
||||
PathUtil.moveContent(
|
||||
FileUtil.file("d:/test/dir1/test1.txt").toPath(),
|
||||
FileUtil.file("d:/test/test2").toPath(), false);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user