问题
1、查看指定文件及其子目录中文件名为【数字.xls】形式的文件,例如123.xls,456.xls等。
2、上述问题1中查找的文件有两个内容完全一致,请找出完全一致的两个文件。
代码
public class Test {
public static void main(String[] args) {
// 被遍历的文件夹
File dirFile = new File("C:\\test\\data");
// 所有xls文件(名称是数字)的名称列表
List<File> list = searchFile(dirFile);
// 提示语
System.out.println("打印所有xls文件(名称是数字)列表:");
// 打印所有xls文件(名称是数字)的名称,验证我是否真的获取到了
for (File file : list) {
System.out.println(file.getName());
}
System.out.println("******************************分隔符******************************");
// Map中的key是我自己生成的,value中的List集合中装着那两个具有完全相同内容的文件
Map<Integer, List<File>> map = getSameFile(list);
// 提示语
System.out.println("打印所有内容完全相同的xls文件(名称是数字):");
// 遍历map集合,找出那些具有完全相同内容的文件
Set<Integer> set = map.keySet();
for (Integer num : set) {
List<File> files = map.get(num);
System.out.println("1号文件:" + files.get(0).getName() + ";2号文件:" + files.get(1).getName());
}
}
/**
* 获取所有xls文件(名称是数字)的名称列表
*
* @param dirFile 被遍历的文件夹
* @return 所有xls文件(名称是数字)的名称列表
*/
private static List<File> searchFile(File dirFile) {
// 放置所有xls文件(名称是数字)的名称列表
List<File> list = new ArrayList<>();
// 调用方法,将所有xls文件(名称是数字)放入列表中
addFileToList(list, dirFile);
// 返回所有xls文件(名称是数字)的名称列表
return list;
}
/**
* 将xls文件(名称是数字)放入集合中
*
* @param list 所有xls文件(名称是数字)的名称列表
* @param file 被查找的文件夹
*/
private static void addFileToList(List<File> list, File file) {
if (file.isFile()) {
// 1、如果是文件,就将符合条件的文件放入列表中
// 如果该文件的名称是数字,并且以.xls结尾,那就符合要求
if (file.getName().split("\\.xls")[0].matches("-?[1-9]+\\d*") && file.getName().endsWith(".xls")) {
// 将.xls结尾的文件放在集合中
list.add(file);
}
} else {
// 2、如果是文件夹,那么就获得文件夹下面所有的文件
File[] files = file.listFiles();
// 如果文件夹是个空的,那就不用输出了
if (files != null && files.length > 0) {
for (File f : files) {
// 让文件夹中的文件继续去参与判断
addFileToList(list, f);
}
}
}
}
/**
* 获取到底哪些文件的内容是完全相同的
*
* @param list 所有xls文件(名称是数字)的名称列表
* @return 放置所有相同内容文件的映射
*/
private static Map<Integer, List<File>> getSameFile(List<File> list) {
// 放置所有相同内容文件的映射
Map<Integer, List<File>> map = new HashMap<>();
// 当做Map的key
int num = 1;
// 遍历所有xls文件(名称是数字)的名称列表
for (int i = 0; i < list.size() - 1; i++) {
for (int j = i + 1; j < list.size(); j++) {
// 判断两个文件内容是否完全相同
if (testSameFile(list.get(i), list.get(j))) {
// 如果两个文件内容是否完全相同,那么将放入Map中
map.put(num++, Arrays.asList(list.get(i), list.get(j)));
}
}
}
return map;
}
/**
* 判断两个文件内容是否完全相同
*
* @param oneFile 文件1
* @param twoFile 文件2
* @return
*/
private static boolean testSameFile(File oneFile, File twoFile) {
FileInputStream input1 = null;
FileInputStream input2 = null;
try {
input1 = new FileInputStream(oneFile);
input2 = new FileInputStream(twoFile);
// 返回总字节数
int len1 = input1.available();
int len2 = input2.available();
// 如果字节总数长度相同,则比较具体内容
if (len1 == len2) {
// 建立两个字节缓冲区
byte[] data1 = new byte[len1];
byte[] data2 = new byte[len2];
// 将两个文件的内容分别读入缓冲区
input1.read(data1);
input2.read(data2);
// 依次比较文件中的每一个字节
for (int i = 0; i < len1; i++) {
//只要有一个字节不同,两个文件就不一样
if (data1[i] != data2[i]) {
return false;
}
}
return true;
} else {
// 如果字节总数长度不一样,那么文件肯定不同
return false;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭文件流,防止内存泄漏
if (input1 != null) {
try {
input1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (input2 != null) {
try {
input2.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return false;
}
}
结果
打印所有xls文件(名称是数字)列表:
2345022333.xls
-1237635737348658.xls
234456436457.xls
1238979879.xls
2344563643643.xls
******************************分隔符******************************
打印所有内容完全相同的xls文件(名称是数字):
1号文件:2345022333.xls;2号文件:-1237635737348658.xls
1号文件:2345022333.xls;2号文件:234456436457.xls
1号文件:2345022333.xls;2号文件:1238979879.xls
1号文件:2345022333.xls;2号文件:2344563643643.xls
1号文件:-1237635737348658.xls;2号文件:234456436457.xls
1号文件:-1237635737348658.xls;2号文件:1238979879.xls
1号文件:-1237635737348658.xls;2号文件:2344563643643.xls
1号文件:234456436457.xls;2号文件:1238979879.xls
1号文件:234456436457.xls;2号文件:2344563643643.xls
1号文件:1238979879.xls;2号文件:2344563643643.xls