最近发现磁盘空间严重不足,都弹窗提示我了:
想想看到底哪个文件夹占的空间比较大,好做针对性的删除和清理。奈何Windows系统没有查看文件夹大小的工具,只能鼠标放在某个文件夹上,等提示:
AI时代都来临了,就让大语言模型
帮我写一个程序吧:计算指定文件夹中所有文件夹的大小并排序。
初版
于是,我就向大语言模型
提问:
你是一个卓越的Java程序员,计算指定文件夹中所有文件夹的大小并排序。
完整的代码是这样的:
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;public class FolderSizeCalculator {public static void main(String[] args) {// 指定文件夹路径String folderPath = "/path/to/folder";// 获取文件夹列表File folder = new File(folderPath);File[] folderList = folder.listFiles(File::isDirectory);// 计算每个文件夹的大小并存储到ArrayList中ArrayList<Folder> folders = new ArrayList<>();for (File f : folderList) {long size = getFolderSize(f);Folder folderObj = new Folder(f.getName(), size);folders.add(folderObj);}// 根据文件夹大小进行排序Collections.sort(folders, Comparator.comparingLong(Folder::getSize));// 输出结果for (Folder f : folders) {System.out.println(f.getName() + " - " + formatSize(f.getSize()));}}// 递归计算文件夹大小public static long getFolderSize(File folder) {long size = 0;File[] fileList = folder.listFiles();if (fileList != null) {for (File f : fileList) {if (f.isFile()) {size += f.length();} else {size += getFolderSize(f);}}}return size;}// 格式化文件大小public static String formatSize(long size) {String[] units = {"B", "KB", "MB", "GB", "TB"};int i = 0;double s = size;while (s >= 1024 && i < units.length - 1) {s /= 1024;i++;}return String.format("%.2f %s", s, units[i]);}
}// 文件夹类
class Folder {private String name;private long size;public Folder(String name, long size) {this.name = name;this.size = size;}public String getName() {return name;}public long getSize() {return size;}
}
使用File
类获取指定文件夹中的所有子文件夹,然后使用递归函数getFolderSize
计算每个文件夹的大小,最后将结果存储到一个ArrayList
中。程序使用Collections.sort
方法根据文件夹大小对ArrayList
进行排序,并使用formatSize
方法格式化文件大小并输出结果。
修改一下指定文件夹的路径就可以运行,效果还不错:
社 - 646.13 KB
学 - 141.15 MB
猫 - 587.99 MB
万 - 1.52 GB
唯一有一点小瑕疵,排序是从小到大的,稍微做一下修改,把
// 根据文件夹大小进行排序
Collections.sort(folders, Comparator.comparingLong(Folder::getSize));
修改为:
// 根据文件夹大小进行排序
Collections.sort(folders, (f1, f2) -> Long.compare(f2.getSize(), f1.getSize()));
运行一下,看看效果:
万 - 1.52 GB
猫 - 587.99 MB
学 - 141.15 MB
社 - 646.13 KB
进化
每次修改需要计算的文件夹路径时,都需要修改代码重新运行,很不方便。我想到了Swing,可以用UI进行交互。于是,我又向大语言模型
重新提问:
你是一个卓越的Java程序员,计算指定文件夹中所有文件夹的大小并排序,要求是使用Swing交互,包括输入指定文件夹、展示文件夹大小。
完整的代码如下:
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
import javax.swing.*;public class FolderSizeSorter extends JFrame {private JLabel directoryLabel;private JTextField directoryTextField;private JButton calculateButton;private JTextArea resultTextArea;public FolderSizeSorter() {super("Folder Size Sorter");// set up UI componentsdirectoryLabel = new JLabel("Directory:");directoryTextField = new JTextField(20);calculateButton = new JButton("Calculate");resultTextArea = new JTextArea(20, 40);JScrollPane scrollPane = new JScrollPane(resultTextArea);// set up layoutJPanel inputPanel = new JPanel();inputPanel.add(directoryLabel);inputPanel.add(directoryTextField);inputPanel.add(calculateButton);add(inputPanel, BorderLayout.NORTH);add(scrollPane, BorderLayout.CENTER);// set up event listenerscalculateButton.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {calculateFolderSizes();}});// set up window propertiessetDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setSize(500, 400);setVisible(true);}private void calculateFolderSizes() {String directoryPath = directoryTextField.getText();File directory = new File(directoryPath);if (!directory.isDirectory()) {JOptionPane.showMessageDialog(this, "Please enter a valid directory path.");return;}Map<File, Long> folderSizes = new HashMap<>();calculateFolderSizesRecursive(directory, folderSizes);List<Map.Entry<File, Long>> folderSizesList = new ArrayList<>(folderSizes.entrySet());Collections.sort(folderSizesList, new Comparator<Map.Entry<File, Long>>() {public int compare(Map.Entry<File, Long> o1, Map.Entry<File, Long> o2) {return o2.getValue().compareTo(o1.getValue());}});resultTextArea.setText("");for (Map.Entry<File, Long> folderSize : folderSizesList) {resultTextArea.append(folderSize.getKey().getPath() + " - " + formatSize(folderSize.getValue()) + "\n");}}private void calculateFolderSizesRecursive(File folder, Map<File, Long> folderSizes) {File[] files = folder.listFiles();if (files == null) {return;}long folderSize = 0;for (File file : files) {if (file.isDirectory()) {calculateFolderSizesRecursive(file, folderSizes);folderSize += folderSizes.get(file);} else {folderSize += file.length();}}folderSizes.put(folder, folderSize);}private String formatSize(long size) {String[] units = {"B", "KB", "MB", "GB", "TB"};int unitIndex = 0;double dSize = size;while (dSize >= 1024 && unitIndex < units.length - 1) {dSize /= 1024;unitIndex++;}return String.format("%.2f %s", dSize, units[unitIndex]);}public static void main(String[] args) {new FolderSizeSorter();}
}
创建了一个GUI窗口,包括一个标签、一个文本框、一个按钮,在文本框输入文件夹的路径,点击“Calculate”就可以了,效果如下图:
再进化
在使用过程中,又有了新的问题:我看到某一个文件夹比较大,想再看看这个文件夹下的文件夹大小情况,还得手动复制粘贴文件夹路径重新计算,操作起来不是很方便。于是,我又向大语言模型
重新提问:
你是一个卓越的Java程序员,计算指定文件夹中所有文件夹的大小并排序,要求是使用Swing交互,包括:输入指定文件夹、以树型结构展示文件夹的大小。
完整的代码如下:
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;public class FolderSizeCalculator extends JFrame {private static final long serialVersionUID = 1L;private JPanel contentPane;private JButton btnSelectFolder;private JTree tree;private DefaultTreeModel treeModel;/*** Launch the application.*/public static void main(String[] args) {EventQueue.invokeLater(new Runnable() {public void run() {try {FolderSizeCalculator frame = new FolderSizeCalculator();frame.setVisible(true);} catch (Exception e) {e.printStackTrace();}}});}/*** Create the frame.*/public FolderSizeCalculator() {setTitle("Folder Size Calculator");setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setBounds(100, 100, 450, 300);contentPane = new JPanel();contentPane.setLayout(new BorderLayout(0, 0));setContentPane(contentPane);btnSelectFolder = new JButton("Select Folder");btnSelectFolder.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {JFileChooser fileChooser = new JFileChooser();fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);int result = fileChooser.showOpenDialog(FolderSizeCalculator.this);if (result == JFileChooser.APPROVE_OPTION) {File folder = fileChooser.getSelectedFile();DefaultMutableTreeNode root = new DefaultMutableTreeNode(folder.getName());treeModel = new DefaultTreeModel(root);tree.setModel(treeModel);calculateFolderSize(folder, root);tree.expandRow(0);}}});contentPane.add(btnSelectFolder, BorderLayout.NORTH);JScrollPane scrollPane = new JScrollPane();contentPane.add(scrollPane, BorderLayout.CENTER);tree = new JTree();scrollPane.setViewportView(tree);}private void calculateFolderSize(File folder, DefaultMutableTreeNode node) {long size = 0;List<File> subfolders = new ArrayList<>();for (File file : folder.listFiles()) {if (file.isDirectory()) {subfolders.add(file);} else {size += file.length();}}Collections.sort(subfolders);for (File subfolder : subfolders) {DefaultMutableTreeNode subnode = new DefaultMutableTreeNode(subfolder.getName());node.add(subnode);calculateFolderSize(subfolder, subnode);}node.setUserObject(node.getUserObject() + " (" + humanReadableByteCount(size, false) + ")");}private String humanReadableByteCount(long bytes, boolean si) {int unit = si ? 1000 : 1024;if (bytes < unit)return bytes + " B";int exp = (int) (Math.log(bytes) / Math.log(unit));String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp - 1) + (si ? "" : "i");return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre);}
}
这个程序中,创建了一个继承自JFrame
的FolderSizeCalculator
类,并在其中创建了一个用户界面。
我们可以通过点击“Select Folder”按钮来选择要计算大小的文件夹。一旦用户选择了一个文件夹,程序将会计算该文件夹中所有文件夹的大小,并将结果以树形结构展示出来。
计算文件夹大小的方法是calculateFolderSize
,它使用递归来遍历文件夹及其子文件夹,计算它们的大小。该方法将每个子文件夹作为一个节点添加到树中,并将文件夹大小添加到节点名称中。
humanReadableByteCount
是一个辅助方法,用于将文件大小从字节转换为人类可读的格式(如MB、GB等)。
运行一下,看看效果:
发现了问题,子文件夹的大小反而比父文件夹的大,仔细阅读了一下代码发现:在calculateFolderSize
方法中累加了文件的大小,没有累加子文件夹的大小。于是,我又向大语言模型
重新提问:
你是一个卓越的Java程序员,把以下方法改下成计算文件下所有文件夹和文件的大小的总和
大语言模型
增加了一个calculateTotalSize
方法:
private long calculateTotalSize(File folder) {long totalSize = 0;if (folder.isDirectory()) {for (File file : folder.listFiles()) {if (file.isDirectory()) {totalSize += calculateTotalSize(file);} else {totalSize += file.length();}}} else {totalSize = folder.length();}return totalSize;
}
在该方法中,首先检查传递的文件夹是否是文件夹类型。如果是文件夹,则迭代遍历其所有子项,如果子项是文件夹,则递归调用该方法以计算其大小;如果子项是文件,则将其大小加到总大小中。如果传递的文件夹是文件,则直接返回其大小。最终,该方法返回总大小。
将以上方法集成到原有方法中,用于计算文件夹下所有文件和文件夹的大小总和。以下是修改后的示例代码:
private void calculateFolderSize(File folder, DefaultMutableTreeNode node) {long size = calculateTotalSize(folder);List<File> subfolders = new ArrayList<>();for (File file : folder.listFiles()) {if (file.isDirectory()) {subfolders.add(file);}}Collections.sort(subfolders);for (File subfolder : subfolders) {DefaultMutableTreeNode subnode = new DefaultMutableTreeNode(subfolder.getName());node.add(subnode);calculateFolderSize(subfolder, subnode);}node.setUserObject(node.getUserObject() + " (" + humanReadableByteCount(size, false) + ")");
}
我们可以发现大语言模型
修改后的代码性能不是很好,因为calculateFolderSize
方法就是一个递归方法,在这个递归方法里还要对每个文件夹再做一次递归。
我们完全可以在一次递归中完成整个计算过程。于是,我又向大语言模型
重新提问:
你是一个卓越的Java程序员,把以下方法改写为计算文件下所有文件夹和文件的大小的总和,要求性能最优:
很遗憾,我虽然给大语言模型
扣上了卓越的帽子,但回答仍然不理想。
只能自己动手了,把calculateFolderSize
方法修改为:
private long calculateFolderSize(File folder, DefaultMutableTreeNode node) {long size = 0;Map<DefaultMutableTreeNode, Long> nodeMap = new HashMap<>();for (File file : folder.listFiles()) {if (file.isDirectory()) {DefaultMutableTreeNode subnode = new DefaultMutableTreeNode(file.getName());long subSize = calculateFolderSize(file, subnode);nodeMap.put(subnode, subSize);size += subSize;} else {size += file.length();}}List<Entry<DefaultMutableTreeNode, Long>> nodes = new ArrayList<>(nodeMap.entrySet());Collections.sort(nodes, (o1,o2)-> o2.getValue().compareTo(o1.getValue()));for (Map.Entry<DefaultMutableTreeNode, Long> entry : nodes) {node.add(entry.getKey());}node.setUserObject(node.getUserObject() + " (" + humanReadableByteCount(size, false) + ")");return size;
}
运行一下,看看效果:
结尾
自从大语言模型
等AI技术在全球范围内广泛应用以来,许多人开始担忧自己是否会被AI所取代。尽管AI在众多领域展现出了惊人的能力,但要想完全替代人类,仍需克服诸多难题。
在本文中,尽管AI已经展示出较高的技术水平,但它仍然需要我的改进和优化来完成我所提供的任务。AI可以被视为一种工具,协助我解决复杂问题,提高工作效率。
因此,真正可能替代你的并非AI本身,而是那些能够熟练运用AI技术的人。
附:最终完整代码
import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;public class FolderSizeCalculator extends JFrame {private static final long serialVersionUID = 1L;private JPanel contentPane;private JButton btnSelectFolder;private JTree tree;private DefaultTreeModel treeModel;/*** Launch the application.*/public static void main(String[] args) {EventQueue.invokeLater(() -> {try {FolderSizeCalculator frame = new FolderSizeCalculator();frame.setVisible(true);} catch (Exception e) {e.printStackTrace();}});}/*** Create the frame.*/public FolderSizeCalculator() {setTitle("Folder Size Calculator");setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setBounds(100, 100, 450, 300);contentPane = new JPanel();contentPane.setLayout(new BorderLayout(0, 0));setContentPane(contentPane);btnSelectFolder = new JButton("Select Folder");btnSelectFolder.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {JFileChooser fileChooser = new JFileChooser();fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);int result = fileChooser.showOpenDialog(FolderSizeCalculator.this);if (result == JFileChooser.APPROVE_OPTION) {File folder = fileChooser.getSelectedFile();DefaultMutableTreeNode root = new DefaultMutableTreeNode(folder.getName());treeModel = new DefaultTreeModel(root);tree.setModel(treeModel);calculateFolderSize(folder, root);tree.expandRow(0);}}});contentPane.add(btnSelectFolder, BorderLayout.NORTH);JScrollPane scrollPane = new JScrollPane();contentPane.add(scrollPane, BorderLayout.CENTER);tree = new JTree();scrollPane.setViewportView(tree);}private long calculateFolderSize(File folder, DefaultMutableTreeNode node) {long size = 0;Map<DefaultMutableTreeNode, Long> nodeMap = new HashMap<>();for (File file : folder.listFiles()) {if (file.isDirectory()) {DefaultMutableTreeNode subnode = new DefaultMutableTreeNode(file.getName());long subSize = calculateFolderSize(file, subnode);nodeMap.put(subnode, subSize);size += subSize;} else {size += file.length();}}List<Entry<DefaultMutableTreeNode, Long>> nodes = new ArrayList<>(nodeMap.entrySet());nodes.sort((o1, o2) -> o2.getValue().compareTo(o1.getValue()));for (Map.Entry<DefaultMutableTreeNode, Long> entry : nodes) {node.add(entry.getKey());}node.setUserObject(node.getUserObject() + " (" + humanReadableByteCount(size, false) + ")");return size;}private String humanReadableByteCount(long bytes, boolean si) {int unit = si ? 1000 : 1024;if (bytes < unit) {return bytes + " B";}int exp = (int) (Math.log(bytes) / Math.log(unit));String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp - 1) + (si ? "" : "i");return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre);}}