背景:
window 用久了磁盘变红了,又不想安装大文件分析的软件,突发奇想能否自己写一个代码,分析有哪些大文件
文件的单位,最高记作G
// 文件大小单位
static String[] fileSizeUnits = {"B", "KB", "M", "G"};
计算文件或者文件夹的大小
/**
* 得到文件大小
* @param folder
* @return
*/
public static long getFileSize(File folder) {
if (!folder.isDirectory()) {
return folder.length();
}
long size = 0;
File[] files = folder.listFiles();
if (files != null) {
for (File file : files) {
if (file.isFile()) {
size += file.length();
} else {
size += getFileSize(file);
}
}
}
return size;
}
打印文件大小信息
/**
* 打印文件大小
*
* @param fileSizeUnits 文件大小单位
* @param fileSize 文件大小
* @param index 单位的下标
* @param tempSize 当前文件单位对应的Byte大小
*/
public static void print(String[] fileSizeUnits, long fileSize, int index, long tempSize) {
// 达到最大单位
if (index >= fileSizeUnits.length - 1) {
System.out.print(" " + fileSize / tempSize + "" + fileSizeUnits[index]);
return;
}
// 能否达到下一个单位
if (fileSize >= tempSize * 1024) {
// 进入下一个单位
print(fileSizeUnits, fileSize, index + 1, tempSize * 1024);
// 输出本单位
System.out.print(" " + (fileSize % (tempSize * 1024)) / tempSize + "" + fileSizeUnits[index]);
return;
}
System.out.print(" " + fileSize / tempSize + "" + fileSizeUnits[index]);
}
获取指定文件夹的文件大小信息,支持找最大的几个文件,找几层
/**
* @param files: 文件
* @param level 目前是第几层
* @param endLevel 分析到第几层
* @param topK 只找前面的几个文件,为空标识不限制
*/
public static void show(List<File> files, int level, int endLevel, Integer topK) {
if (files.isEmpty() || level >= endLevel) {
return;
}
String spitLine = "-----------------------%s-------------------\n";
System.out.println(String.format(spitLine, level));
Map<String, Long> sizeMap = new HashMap<>();
files.forEach(e -> sizeMap.put(e.getAbsolutePath(), getFileSize(e)));
Collections.sort(files, (a, b) -> {
long r = sizeMap.get(b.getAbsolutePath()) - sizeMap.get(a.getAbsolutePath());
if (r == 0) {
return 0;
}
return r > 0 ? 1 : -1;
});
int k = 0;
for (File file : files) {
if (topK != null && k++ > topK) {
break;
}
long folderSize = sizeMap.get(file.getAbsolutePath());
System.out.print(file.getAbsoluteFile() + "\t");
print(fileSizeUnits, folderSize, 0, 1);
System.out.println();
}
System.out.println(String.format(spitLine, level));
System.out.println();
List<File> nextFile = new ArrayList<>();
for (File file : files) {
if (file.isDirectory()) {
File[] arr = file.listFiles();
if (arr == null) {
continue;
}
nextFile.addAll(Arrays.asList(arr));
}
}
show(nextFile, level + 1, endLevel, topK);
}
测试如下:
String path = "C:\\Users\\xxx";
File file = new File(path);
show(Arrays.asList(file), 1, 3, 10);
执行结果如下