This commit is contained in:
Looly 2022-10-24 22:47:18 +08:00
parent 106e465014
commit 267e16e9c1

View File

@ -27,22 +27,32 @@ import java.util.ArrayList;
* @author Looly
* @since 3.0.9
*/
public class FileCopier extends SrcToDestCopier<File, FileCopier>{
public class FileCopier extends SrcToDestCopier<File, FileCopier> {
private static final long serialVersionUID = 1L;
/** 是否覆盖目标文件 */
/**
* 是否覆盖目标文件
*/
private boolean isOverride;
/** 是否拷贝所有属性 */
/**
* 是否拷贝所有属性
*/
private boolean isCopyAttributes;
/** 当拷贝来源是目录时是否只拷贝目录下的内容 */
/**
* 当拷贝来源是目录时是否只拷贝目录下的内容
*/
private boolean isCopyContentIfDir;
/** 当拷贝来源是目录时是否只拷贝文件而忽略子目录 */
/**
* 当拷贝来源是目录时是否只拷贝文件而忽略子目录
*/
private boolean isOnlyCopyFile;
//-------------------------------------------------------------------------------------------------------- static method start
/**
* 新建一个文件复制器
* @param srcPath 源文件路径相对ClassPath路径或绝对路径
*
* @param srcPath 源文件路径相对ClassPath路径或绝对路径
* @param destPath 目标文件路径相对ClassPath路径或绝对路径
* @return this
*/
@ -52,7 +62,8 @@ public class FileCopier extends SrcToDestCopier<File, FileCopier>{
/**
* 新建一个文件复制器
* @param src 源文件
*
* @param src 源文件
* @param dest 目标文件
* @return this
*/
@ -62,9 +73,11 @@ public class FileCopier extends SrcToDestCopier<File, FileCopier>{
//-------------------------------------------------------------------------------------------------------- static method end
//-------------------------------------------------------------------------------------------------------- Constructor start
/**
* 构造
* @param src 源文件
*
* @param src 源文件
* @param dest 目标文件
*/
public FileCopier(final File src, final File dest) {
@ -74,15 +87,19 @@ public class FileCopier extends SrcToDestCopier<File, FileCopier>{
//-------------------------------------------------------------------------------------------------------- Constructor end
//-------------------------------------------------------------------------------------------------------- Getters and Setters start
/**
* 是否覆盖目标文件
*
* @return 是否覆盖目标文件
*/
public boolean isOverride() {
return isOverride;
}
/**
* 设置是否覆盖目标文件
*
* @param isOverride 是否覆盖目标文件
* @return this
*/
@ -93,13 +110,16 @@ public class FileCopier extends SrcToDestCopier<File, FileCopier>{
/**
* 是否拷贝所有属性
*
* @return 是否拷贝所有属性
*/
public boolean isCopyAttributes() {
return isCopyAttributes;
}
/**
* 设置是否拷贝所有属性
*
* @param isCopyAttributes 是否拷贝所有属性
* @return this
*/
@ -110,6 +130,7 @@ public class FileCopier extends SrcToDestCopier<File, FileCopier>{
/**
* 当拷贝来源是目录时是否只拷贝目录下的内容
*
* @return 当拷贝来源是目录时是否只拷贝目录下的内容
*/
public boolean isCopyContentIfDir() {
@ -118,6 +139,7 @@ public class FileCopier extends SrcToDestCopier<File, FileCopier>{
/**
* 当拷贝来源是目录时是否只拷贝目录下的内容
*
* @param isCopyContentIfDir 是否只拷贝目录下的内容
* @return this
*/
@ -166,9 +188,9 @@ public class FileCopier extends SrcToDestCopier<File, FileCopier>{
* @throws IORuntimeException IO异常
*/
@Override
public File copy() throws IORuntimeException{
public File copy() throws IORuntimeException {
final File src = this.src;
final File dest = this.dest;
File dest = this.dest;
// check
Assert.notNull(src, "Source File is null !");
if (false == src.exists()) {
@ -180,28 +202,29 @@ public class FileCopier extends SrcToDestCopier<File, FileCopier>{
}
if (src.isDirectory()) {// 复制目录
if(dest.exists() && false == dest.isDirectory()) {
if (dest.exists() && false == dest.isDirectory()) {
//源为目录目标为文件抛出IO异常
throw new IORuntimeException("Src is a directory but dest is a file!");
}
if(FileUtil.isSub(src, dest)) {
if (FileUtil.isSub(src, dest)) {
throw new IORuntimeException("Dest is a sub directory of src !");
}
final File subTarget = isCopyContentIfDir ? dest : FileUtil.mkdir(FileUtil.file(dest, src.getName()));
internalCopyDirContent(src, subTarget);
} else {// 复制文件
internalCopyFile(src, dest);
dest = internalCopyFile(src, dest);
}
return dest;
}
//----------------------------------------------------------------------------------------- Private method start
/**
* 拷贝目录内容只用于内部不做任何安全检查<br>
* 拷贝内容的意思为源目录下的所有文件和目录拷贝到另一个目录下而不拷贝源目录本身
*
* @param src 源目录
* @param src 源目录
* @param dest 目标目录
* @throws IORuntimeException IO异常
*/
@ -220,7 +243,7 @@ public class FileCopier extends SrcToDestCopier<File, FileCopier>{
}
final String[] files = src.list();
if(ArrayUtil.isNotEmpty(files)){
if (ArrayUtil.isNotEmpty(files)) {
File srcFile;
File destFile;
for (final String file : files) {
@ -244,37 +267,38 @@ public class FileCopier extends SrcToDestCopier<File, FileCopier>{
* 2如果目标是一个已存在的目录则文件拷贝到此目录下文件名与原文件名一致
* </pre>
*
* @param src 源文件必须为文件
* @param src 源文件必须为文件
* @param dest 目标文件如果非覆盖模式必须为目录
* @return 目标文件
* @throws IORuntimeException IO异常
*/
private void internalCopyFile(final File src, File dest) throws IORuntimeException {
private File internalCopyFile(final File src, File dest) throws IORuntimeException {
if (null != copyPredicate && false == copyPredicate.test(src)) {
//被过滤的文件跳过
return;
return dest;
}
// 如果已经存在目标文件切为不覆盖模式跳过之
if (dest.exists()) {
if(dest.isDirectory()) {
if (dest.isDirectory()) {
//目标为目录目录下创建同名文件
dest = new File(dest, src.getName());
}
if(dest.exists() && false == isOverride) {
if (dest.exists() && false == isOverride) {
//非覆盖模式跳过
return;
return dest;
}
}else {
} else {
//路径不存在则创建父目录
FileUtil.mkParentDirs(dest);
}
final ArrayList<CopyOption> optionList = new ArrayList<>(2);
if(isOverride) {
if (isOverride) {
optionList.add(StandardCopyOption.REPLACE_EXISTING);
}
if(isCopyAttributes) {
if (isCopyAttributes) {
optionList.add(StandardCopyOption.COPY_ATTRIBUTES);
}
@ -283,6 +307,7 @@ public class FileCopier extends SrcToDestCopier<File, FileCopier>{
} catch (final IOException e) {
throw new IORuntimeException(e);
}
return dest;
}
//----------------------------------------------------------------------------------------- Private method end
}