diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/io/file/FileUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/io/file/FileUtil.java
index 1a641adbc..653b88812 100644
--- a/hutool-core/src/main/java/org/dromara/hutool/core/io/file/FileUtil.java
+++ b/hutool-core/src/main/java/org/dromara/hutool/core/io/file/FileUtil.java
@@ -967,7 +967,7 @@ public class FileUtil extends PathUtil {
* 将文件写入流中,此方法不会关闭输出流
*
* @param src 文件
- * @param out 流
+ * @param out 流
* @return 写出的流byte数
* @throws IORuntimeException IO异常
* @since 6.0.0
@@ -984,7 +984,7 @@ public class FileUtil extends PathUtil {
* 如果目标文件为目录,则将源文件以相同文件名拷贝到目标目录
*
* @param srcPath 源文件或目录
- * @param targetPath 目标文件或目录,目标不存在会自动创建(目录、文件都创建)
+ * @param targetPath 目标文件或目录,目标不存在会自动创建(目录、文件都创建)
* @param isOverride 是否覆盖目标文件
* @return 目标目录或文件
* @throws IORuntimeException IO异常
@@ -1275,23 +1275,38 @@ public class FileUtil extends PathUtil {
/**
* 检查两个文件是否是同一个文件
- * 所谓文件相同,是指File对象是否指向同一个文件或文件夹
+ * 所谓文件相同,是指File对象是否指向同一个文件或文件夹,规则为:
+ *
+ * - 当两个文件都为{@code null}时,返回{@code true}
+ * - 当两个文件都存在时,检查是否为同一个文件
+ * - 当两个文件都不存在时,检查路径是否一致
+ *
*
- * @param file1 文件1
- * @param file2 文件2
+ * @param file1 文件1,可以为{@code null}
+ * @param file2 文件2,可以为{@code null}
* @return 是否相同
* @throws IORuntimeException IO异常
*/
public static boolean equals(final File file1, final File file2) throws IORuntimeException {
- Assert.notNull(file1);
- Assert.notNull(file2);
- if (!file1.exists() || !file2.exists()) {
- // 两个文件都不存在判断其路径是否相同, 对于一个存在一个不存在的情况,一定不相同
- return !file1.exists()//
- && !file2.exists()//
- && pathEquals(file1, file2);
+ // 都为null认定为相同
+ if (null == file1 || null == file2) {
+ return null == file1 && null == file2;
}
- return equals(file1.toPath(), file2.toPath());
+
+ final boolean exists1 = file1.exists();
+ final boolean exists2 = file2.exists();
+
+ // 当两个文件都存在时,检查是否为同一个文件
+ if (exists1 && exists2) {
+ return PathUtil.isSameFile(file1.toPath(), file2.toPath());
+ }
+
+ // 都不存在时,检查路径是否相同
+ if (!exists1 && !exists2) {
+ return pathEquals(file1, file2);
+ }
+
+ return false;
}
/**
diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/io/file/PathMover.java b/hutool-core/src/main/java/org/dromara/hutool/core/io/file/PathMover.java
index 5053a419b..05af30083 100644
--- a/hutool-core/src/main/java/org/dromara/hutool/core/io/file/PathMover.java
+++ b/hutool-core/src/main/java/org/dromara/hutool/core/io/file/PathMover.java
@@ -96,7 +96,7 @@ public class PathMover {
final CopyOption[] options = this.options;
if (PathUtil.isSub(src, target)) {
- if(Files.exists(target) && PathUtil.equals(src, target)){
+ if(PathUtil.equals(src, target)){
// issue#2845,当用户传入目标路径与源路径一致时,直接返回,否则会导致删除风险。
return target;
}
@@ -144,15 +144,11 @@ public class PathMover {
*/
public Path moveContent() {
final Path src = this.src;
- if (PathUtil.isExistsAndNotDirectory(target, false)) {
- // 文件移动调用move方法
- return move();
- }
-
final Path target = this.target;
+
+ // 文件移动调用move方法
if (PathUtil.isExistsAndNotDirectory(target, false)) {
- // 目标不能为文件
- throw new IllegalArgumentException("Can not move dir content to a file");
+ return move();
}
// issue#2893 target 不存在导致NoSuchFileException
diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/io/file/PathUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/io/file/PathUtil.java
index 9412259ec..e505803f7 100644
--- a/hutool-core/src/main/java/org/dromara/hutool/core/io/file/PathUtil.java
+++ b/hutool-core/src/main/java/org/dromara/hutool/core/io/file/PathUtil.java
@@ -19,6 +19,7 @@ import org.dromara.hutool.core.io.resource.FileResource;
import org.dromara.hutool.core.io.resource.Resource;
import org.dromara.hutool.core.lang.Assert;
import org.dromara.hutool.core.util.CharsetUtil;
+import org.dromara.hutool.core.util.ObjUtil;
import java.io.*;
import java.nio.charset.Charset;
@@ -611,6 +612,11 @@ public class PathUtil {
/**
* 检查两个文件是否是同一个文件
* 所谓文件相同,是指Path对象是否指向同一个文件或文件夹
+ *
+ * - 当两个文件都为{@code null}时,返回{@code true}
+ * - 当两个文件都存在时,检查是否为同一个文件
+ * - 当两个文件都不存在时,检查Path对象是否equals
+ *
*
* @param file1 文件1
* @param file2 文件2
@@ -620,6 +626,34 @@ public class PathUtil {
* @since 5.4.1
*/
public static boolean equals(final Path file1, final Path file2) throws IORuntimeException {
+ // 都为null认定为相同
+ if(null == file1 || null == file2){
+ return null == file1 && null == file2;
+ }
+
+ final boolean exists1 = exists(file1, false);
+ final boolean exists2 = exists(file2, false);
+
+
+ if(exists1 && exists2){
+ return isSameFile(file1, file2);
+ }
+
+ return ObjUtil.equals(file1, file2);
+ }
+
+ /**
+ * 检查两个文件是否是同一个文件
+ * 所谓文件相同,是指Path对象是否指向同一个文件或文件夹
+ *
+ * @param file1 文件1,必须存在
+ * @param file2 文件2,必须存在
+ * @return 是否相同
+ * @throws IORuntimeException IO异常
+ * @see Files#isSameFile(Path, Path)
+ * @since 6.0.0
+ */
+ public static boolean isSameFile(final Path file1, final Path file2) throws IORuntimeException {
try {
return Files.isSameFile(file1, file2);
} catch (final IOException e) {