【任务描述】
编写一个模拟文件管理器的程序,实现控制台对文件和文件夹的管理操作。此程序中,当用户输入指令 1 时,代表“指定关键字检索文件”,此时需要用户输入检索的目录和关键字,系统在用户指定的目录下检索出文件名中包含关键字的文件,并将其绝对路径展示出来。指令 2 代表“指定后缀名检索文件”,此时需要用户输入检索的目录和后缀名(可输入由逗号分割的多个后缀名,来实现同时对不同后缀名文件的搜索),系统在用户指定的目录下检索出指定后缀名的文件,并将其绝对路径展示出来。指令 3 代表“复制文件/目录”,此时需要用户输入源目录和目标目录,程序执行后会将源目录下的内容复制到目标目录下。指令 4 代表“退出”,即退出系统。
【实现思路】**
- 根据任务介绍和运行结果分析可知,首先需要创建一个文件管理器类。可以在类中使用 while 循环实现控制台中操作指令的多次输入,并使用 switch 语句根据控制台输入的操作指令来判断执行什么操作。
- 执行指令 1 时,代表指定关键词引索文件,即在目录下查找包含关键词的文件。执行时先要从控制台获取目录和关键字,然后将其传到后台的方法中,后台可将传入的关键字利用过滤器制定成“规则”,通过递归的方式遍历文件夹,在每个子文件夹下调用过滤镜,来获取符合规则的文件路径,并将集合返回,最后打印出来。
- 执行指令 2 时,代表指定后缀名检索文件,即在目录下查找名称结尾是指定后缀的文件。执行时可以先从控制台获取目录和后缀名,然将后缀名拆分成数组,并将数组和目录传到后台方法中。后台可用过滤器将后缀名数组循环遍历,制定成“规则”,通过递归的方式遍历文件夹,在每个子文件夹下调用过滤器,来获取符合规则的文件路径的集合,并将集合返回,最后打印出来。
- 执行指令 3 时,代表将源目录的内容复制到目标目录中。执行时可以先从控制台获取源目录和目标目录,然后将其传入后台。后台主要时通过递归的方法执行文件和文件夹复制的。每次调用此方法时,首先会获取当前目录下的文件和文件夹列表,然后循环列表并判断当前元素是文件还是文件夹。如果是文件夹,就利用 File 类的 mkdirs()方法在目标目录中创建此文件夹,再调用自身;如果是文件,由于不一定是纯文本文件,所以可以采用字节流将文件写入到目标目录。
- 执行指令 4 时,执行退出该程序的操作,该操作可以通过 System.exit(0)来实现。
【实现代码】
1、定义 DocumentManager 类,具体如下所示。
import java.awt.List;
import java.io.File;
import java.util.ArrayList;
import java.util.Scanner;
public class DocumentManager {
public static void main(String[] args) throws Exception{
Scanner sc = new Scanner(System.in);
System.out.println("==1:指定关键字检索文件 2:指定后缀名检索文件 3:复制文件/目录 4:退出==");
while (true) {
System.out.println("请输入指令");
int command = sc.nextInt();
switch (command) {
case 1:
searchByKeyWord(); //指定关键字检索文件
break;
case 2:
searchBusuffix(); //指定后缀名检索文件
break;
case 3:
copyDirectory(); //复制文件/目录
break;
case 4:
exit(); //退出
break;
default:
break;
}
}
}
//***********1.指定关键字检索文件***********
private static void searchByKeyWord() {
Scanner sc = new Scanner(System.in);
System.out.println("请输入要检索的目录位置:");
String path = sc.next(); //从控制台获取路径
File file = new File(path);
if (!file.exists() || !file.isDirectory()) {
System.out.println(path + "(不是有效目录)");
return;
}
System.out.println("请输入搜索关键词:");
String key = sc.next(); //获取关键字
//在输入目录下获取所有包含关键字的文件路径
ArrayList<String> list = FileUtils.listFileString(file, key);
for (Object object : list) {
System.out.println(object); //将路径打印到控制台
}
}
//***********2.指定后缀名检索文件***********
private static void searchBusuffix() {
Scanner sc = new Scanner(System.in);
System.out.println("请输入要检索的目录位置:");
String path = sc.next(); //从控制台获取路径
File file = new File(path);
if (!file.exists() || !file.isDirectory()) {
System.out.println(path + "(不是有效目录)");
return;
}
System.out.println("请输入搜索后缀");
String suffix = sc.next();
String[] suffixArray = suffix.split(","); //获取后缀字符串
//在输入目录下获取所有指定后缀名的文件路径
ArrayList<String> list = FileUtils.listFiles(file,suffixArray);
for (Object object : list) {
System.out.println(object); //将路径打印到控制台
}
}
//***********3.复制文件/目录***********
private static void copyDirectory() throws Exception {
Scanner sc = new Scanner(System.in);
System.out.println("请输入源目录:");
String srcDirectory = sc.next(); //从控制台获取源路径
File srcfile = new File(srcDirectory);
if (!srcfile.exists() || !srcfile.isDirectory()) {
System.out.println("无效目录!");
return;
}
System.out.println("请输入目标位置:");
String desDirectory = sc.next(); //从控制台获得目标路径
File desFile = new File(desDirectory);
if (!desFile.exists() || !desFile.isDirectory()) {
System.out.println("无效位置!");
return;
}
//将源路径中的内容复制到目标路径下
FileUtils.copyScrPathToDestPath(srcfile, desFile);
System.out.println("复制成功");
}
//***********4.退出***********
private static void exit() {
System.out.println("您已退出系统,谢谢使用!");
System.exit(0);
}
}
2、定义 FileUtils 类,具体如下所示。
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.util.ArrayList;
import javax.swing.filechooser.FileNameExtensionFilter;
public class FileUtils {
/**
* 指定关键字检索文件
* @param file File 对象
* @param key 关键字
* @return 包含关键字的文件路径
*/
public static ArrayList<String> listFileString(File file, final String key){
FilenameFilter filter = new FilenameFilter() {
@Override
//如果文件名包含关键字返回 true,否则返回 false
public boolean accept(File dir, String name) {
// TODO Auto-generated method stub
File currFile = new File(dir, name);
if (currFile.isFile() && name.contains(key)) {
return true;
}
return false;
}
};
//递归方式获取规定的路径
ArrayList<String> arrayList = fileDir(file, filter);
return arrayList;
}
/**
* 指定后缀检索文件
* @param file File 对象
* @param suffixArrayS 后缀名数组
* @return 指定后缀名的文件路径
*/
public static ArrayList<String> listFiles(File file, final String[] suffixArrayS){
FilenameFilter filter = new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
// TODO Auto-generated method stub
File currFile = new File(dir, name);
if (currFile.isFile()) {
for (String suffix : suffixArrayS) {
if (name.endsWith("." + suffix)) {
return true;
}
}
}
return false;
}
};
//递归方式获取规定的路径
ArrayList<String> arrayList = fileDir(file, filter);
return arrayList;
}
/**
* 递归方式获取规定的路径
* @param dir File 对象
* @param filter 过滤器
* @return 过滤器过滤后的文件路径
*/
public static ArrayList<String> fileDir(File dir, FilenameFilter filter){
ArrayList<String> arrayList = new ArrayList<String>();
File[] lists = dir.listFiles(filter); //获得过滤后的所有文件数组
for (File list : lists) {
//将文件的绝对路径放到集合中
arrayList.add(list.getAbsolutePath());
}
//获得当前目录下所有文件的数组
File[] files = dir.listFiles();
for (File file : files) { //遍历所有的子目录和文件
if (file.isDirectory()) {
//如果是目录,递归调用 fileDir()
ArrayList<String> every = fileDir(file, filter);
arrayList.addAll(every); //将文件夹下的文件路径添加到集合中
}
}//此时的集合中有当前目录下的文件路径,和当前目录的子目录下的文件路径
return arrayList;
}
/**
* 复制目录/文件
* @param srcDir 源目录
* @param desDir 目标目录
* @throws Exception
*/
public static void copyScrPathToDestPath(File srcDir, File desDir) throws Exception{
File[] files = srcDir.listFiles(); //子文件目录
for (int i = 0; i < files.length; i++) {
File copiedFile = new File(desDir, files[i].getName());
if (files[i].isDirectory()) { //如果是目录
if (!copiedFile.mkdir()) {
System.out.println("无法新建此文件夹:“" + copiedFile + "” 因为目标目录下存在该同名文件夹");
return;
}
copyScrPathToDestPath(files[i], copiedFile);
}else {
FileInputStream input = new FileInputStream(files[i]);
FileOutputStream output = new FileOutputStream(copiedFile);
byte[] buffer = new byte[1024];
int n = 0;
while ((n = input.read(buffer)) != -1) {
output.write(buffer, 0, n);
}
input.close();
output.close();
}
}
}
}