文件处理中复制文件是必不可少的,接下来我写了一个子类传递目录路径构造类,在进行调用方法传递新目录路径实现某个目录下所有文件复制到新目录下,并且给出操作记录来详细的记录我复制文件做了那些步骤。那些步骤是否成功。
使用说明:直接创建该类的实例(传递目录路径),在直接使用方法传递新目录进行复制文件(返回布尔值),若为true则是完全复制成功,若为flase则可能是有文件未能复制,或创建目录未成功。一般来说都是文件未能复制成功。
该方法类继承父类,需要用到父类构造的成员字段,该方法也遵从以下几点:
(1) 私有字段保护
在类中的字段不可以被外部更改,以确保类的完整性,需要外部访问的字段开放一个外部获取该字段的方法,方便外部访问。
(2) 良好的判断
首先验证指定目录路径是否纯在,若不存在则创建该文件夹,在进行分批处理,先复制所有文件夹,判断文件夹是否存在,不存在则创建,整体判断文件夹是否完全创建成功,若有文件夹创建失败则停止操作后续,最后进行文件复制,验证文件是否存在,若存在则不允许复制(防止有用文件被覆盖),不存在在进行复制操作。
(3) 详细的注释和提示信息
对所有字段以及方法打上注释,方便维护,给定一个字段(文件是否完全复制成功),在给定一个字段为提示信息的list表格(该字段的类型为自定义的一个内部类,内有(摘要,旧路径,新路径,说明)),保存我对文件做的所有操作。
(4) 重构该类的方法
假如在某一个地方我需要操作多批文件(目录不一致),我可以直接调用重构方法传递新的目录路径使其重新构造该类,无需重新实例该类,还可以减少不必要的实例,加快性能。
/**
* 传递旧目录路径来构造函数
*
* @author 织梦
*/
class CopyFile extends FileHanding {
* 是否完全操作成功
*/
private boolean successfulNo = false;
/**
* 操作记录(提示信息)
*/
private List<MobileRecord> mobileRecord = new ArrayList<MobileRecord>();
/**
* 操作记录(提示信息)类
*
* @author 织梦
*/
class MobileRecord {
/**
* 操作摘要(失败,成功,不合法)
*/
public String summaryInfo;
/**
* 原文件路径
*/
public String oldPath;
/**
* 新文件路径
*/
public String newPath;
/**
* 说明
*/
public String explain;
}
/**
* 获取是否完全操作成功
*
* @return boolean
*/
public boolean getSuccessfulNo() {
return successfulNo;
}
/**
* 获取操作记录(提示信息)
*
* @return List<MobileRecord>
*/
public List<MobileRecord> getMobileRecord() {
return mobileRecord;
}
* 构造函数
*
* @param strPath
*/
public CopyFile(String strPath) {
super(strPath); // 调用父类的构造函数
}
/**
* 若要继续复制其他文件,重新构造该类,减少不必要的实例
*/
public void reconsitutionMoveFile(String strPath) {
this.successfulNo = false; // 初始化提示字段
mobileRecord.clear(); // 初始化移动操作记录
reconsitutionFileHanding(strPath); // 调用父类重构
}
* 设置操作记录(提示信息)
*/
private void setMobileRecord(String summaryInfo, String oldPath,
String newPath, String explain) {
MobileRecord mobileRecord1 = new MobileRecord(); // 实例化操作记录(提示信息)类
mobileRecord1.summaryInfo = summaryInfo; // 操作摘要(失败,成功,不合法)
mobileRecord1.oldPath = oldPath; // 原文件路径
mobileRecord1.newPath = newPath; // 新文件路径
mobileRecord1.explain = explain; // 说明
mobileRecord.add(mobileRecord1); // 添加到操作记录(提示信息)list中
}
逻辑与思维:如何构造类:
构造该类直接调用父类的构造方法构造父类,该类无需构造。若要重新构造将初始化在调用父类重构方法。如何构造父类详情请看文件处理(一)
逻辑与思维:如何复制文件(一):
(1) 调用复制文件方法,传递新目录路径。
(2) 判断父类是否构造成功(若不成功则不继续执行代码,返回false,并且追加一条提示信息)
(3) 判断指定目录是否是原文件路径的子目录。(若不成功则不继续执行代码,返回false,并且追加一条提示信息)
(4) 判断指定目录是否存在,不存在则创建。(添加对应提示信息)
(5) 调用循环方法,循环遍历存储在父类字段中的子目录路径与子文件路径,对其进行相应的操作和判断
* 复制文件到指定目录下
*
* @param strPath
* 指定目录路径
*/
public boolean copyFile(String newPath) {
if (super.getClassSuccessfulNo()) { // 判断父类是否构造成功
// 检测指定目录路径是否是原文件路径的子目录
if (!newPath.contains(super.getStrOldPath())) {
File file = new File(newPath); // 创建File对象
if (file.isDirectory()) { // 判断是否是目录
successfulNo = true; // 标志成功
// 向操作记录(提示信息)表中添加数据
setMobileRecord("创建失败", super.getStrOldPath(), newPath,
"文件夹已纯在");
forCopyFile(newPath); // 调用循环复制文件
} else {
if (file.mkdirs()) { // 判断创建文件夹是否成功
successfulNo = true; // 标志成功
// 向操作记录(提示信息)表中添加数据
setMobileRecord("创建成功", super.getStrOldPath(), newPath,
"创建文件夹成功");
forCopyFile(newPath); // 调用循环复制文件
} else {
// 向操作记录(提示信息)表中添加数据
setMobileRecord("创建失败", super.getStrOldPath(), newPath,
"创建文件夹失败");
}
}
} else {
// 向操作记录(提示信息)表中添加数据
setMobileRecord("不合法", super.getStrOldPath(), newPath,
"移动路径是否是原文件路径的子目录,无法移动。");
}
} else {
setMobileRecord("不合法", super.getStrOldPath(), newPath,
"父类构造失败,旧路径不是一个有效目录");
}
return successfulNo;
}
逻辑与思维:如何复制文件(二):
(1) 获取正则后的旧路径长度。
(2) 创建旧目录路径的File对象用于获取旧目录路径名称。
(3) 获取名称长度,用旧路径长度减去旧目录名称长度。得到需要替换的根目录长度。
(4) 首先遍历目录路径,并在外部声明一个布尔值
(5) 替换根目录,拼接新目录路径。
(6) 判断目录是否存在,不存在则创建。(添加对应提示信息)
(7) 当目录创建失败时停止循环不在执行后续复制文件的循环(目录都创建不完全不能复制文件)
(8) 在循环遍历文件目录,判断是存在同名文件。(存在不进行复制,保证旧文件不会因为操作失误而丢失,添加对应提示信息)
(9) 创建对应的流
(10) 进行复制文件
(11) 复制成功添加对应提示信息
(12) 复制失败则标志失败。同样对应的添加提示信息。
(13) 在finally中关闭流,确保流不会因为出现异常而无法关闭。
(注释:finally修饰的代码块一定会执行,除非JVM虚拟机停止运行)
* 循环复制文件
*/
private void forCopyFile(String newPath) {
int length = super.getStrOldPath().replaceAll("\\/+$", "").length(); // 获取旧路径的长度
File oldFile = new File(super.getStrOldPath()); // 创建旧目录的File对象
length = length - oldFile.getName().length();
List<String> listLibrary = super.getCataloguePath(); // 取出目录路径
boolean b = true; // 用于检测创建文件夹时是否全部创建成功
for (int i = 0; i < listLibrary.size(); i++) {
String strPath = newPath + "/"
+ listLibrary.get(i).substring(length);
File newfile = new File(strPath);
if (!newfile.isDirectory()) { // 判断目录是否纯在
if (newfile.mkdir()) { // 判断创建目录是否成功
// 向操作记录(提示信息)表中添加数据
setMobileRecord("创建成功", listLibrary.get(i), strPath,
"创建文件夹成功");
} else {
successfulNo = false; // 标志失败
// 向操作记录(提示信息)表中添加数据
setMobileRecord("创建失败", listLibrary.get(i), strPath,
"创建文件夹失败");
b = false; // 失败
break;
}
} else {
// 向操作记录(提示信息)表中添加数据
setMobileRecord("创建失败", listLibrary.get(i), strPath, "文件夹已纯在");
}
}
if (b) { // 判断是否全部创建成功
List<String> listFile = super.getFilePath(); // 取出文件路径
for (int i = 0; i < listFile.size(); i++) {
String strPath = newPath + "/"
+ listFile.get(i).substring(length);
File newfile = new File(strPath);
if (!newfile.isFile()) { // 判断是否纯在同名文件
FileChannel inputChannel = null; // 创建流
FileChannel outputChannel = null;
try {
// 复制文件
inputChannel = new FileInputStream(new File(
listFile.get(i))).getChannel();
outputChannel = new FileOutputStream(newfile)
.getChannel();
outputChannel.transferFrom(inputChannel, 0,
inputChannel.size());
setMobileRecord("复制成功", listFile.get(i), strPath,
"复制文件成功");
} catch (IOException e) {
successfulNo = false; // 标志失败
setMobileRecord("复制失败", listFile.get(i), strPath,
"出现异常");
e.printStackTrace();
} finally {
try {
inputChannel.close(); // 关闭流
outputChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} else {
// 向操作记录(提示信息)表中添加数据
setMobileRecord("创建失败", listLibrary.get(i), strPath,
"文件已存在");
successfulNo = false; // 标志失败
}
}
}
}
演示示例:
(1) 直接构造子类
(2) 输出父类目录路径与文件路径
(3) 进行复制,输出成功否与操作记录提示信息