专业的JAVA编程教程与资源

网站首页 > java教程 正文

用java方法编写计算指定目录下所有文件占空间大小

temp10 2025-04-05 22:35:02 java教程 2 ℃ 0 评论
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;

public class DirectorySizeCalculator {

    /**
     * 计算指定目录下所有文件占用的空间大小 (以字节为单位)
     *
     * @param directoryPath 目录路径 (字符串形式)
     * @return  目录下所有文件占用的总空间大小 (字节),如果目录不存在或发生IO异常,返回 -1
     */
    public static long getDirectorySize(String directoryPath) {
        Path dirPath = Paths.get(directoryPath);
        if (!Files.exists(dirPath) || !Files.isDirectory(dirPath)) {
            System.err.println("Error: Directory not found or invalid path: " + directoryPath);
            return -1; // 返回 -1 表示目录不存在或路径无效
        }

        final long[] totalSize = {0}; // 使用数组来在匿名内部类中修改外部变量 (effectively final workaround)

        try {
            Files.walkFileTree(dirPath, new SimpleFileVisitor() {
                @Override
                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                    totalSize[0] += attrs.size(); // 累加文件大小
                    return FileVisitResult.CONTINUE; // 继续遍历
                }

                @Override
                public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
                    System.err.println("Failed to visit file: " + file + ", error: " + exc.getMessage());
                    return FileVisitResult.CONTINUE; // 即使文件访问失败,也继续遍历其他文件
                }
            });
        } catch (IOException e) {
            System.err.println("IO Exception while traversing directory: " + directoryPath + ", error: " + e.getMessage());
            return -1; // 返回 -1 表示发生 IO 异常
        }

        return totalSize[0]; // 返回总大小 (字节)
    }

    /**
     * 将字节大小格式化为更易读的单位 (KB, MB, GB, TB)
     *
     * @param sizeBytes 文件大小 (字节)
     * @return  格式化后的字符串,例如 "1.23 MB"
     */
    public static String formatFileSize(long sizeBytes) {
        if (sizeBytes < 0 return invalid size double size='sizeBytes;' string unit='Bytes' if size>= 1024) {
            size /= 1024;
            unit = "KB";
            if (size >= 1024) {
                size /= 1024;
                unit = "MB";
                if (size >= 1024) {
                    size /= 1024;
                    unit = "GB";
                    if (size >= 1024) {
                        size /= 1024;
                        unit = "TB";
                    }
                }
            }
        }
        return String.format("%.2f %s", size, unit); // 保留两位小数
    }

    public static void main(String[] args) {
        String directoryToCalculate = "./"; // 计算当前目录的大小 (你可以替换为任何目录路径)

        long totalSizeBytes = getDirectorySize(directoryToCalculate);

        if (totalSizeBytes != -1) {
            String formattedSize = formatFileSize(totalSizeBytes);
            System.out.println("目录 '" + directoryToCalculate + "' 占用空间大小: " + formattedSize);
        } else {
            System.out.println("计算目录大小失败.");
        }

        // 测试不存在的目录
        String nonExistentDirectory = "./non_existent_dir";
        long invalidSize = getDirectorySize(nonExistentDirectory);
        if (invalidSize == -1) {
            System.out.println("\n测试不存在的目录 '" + nonExistentDirectory + "': 计算大小失败 (预期结果)");
        }
    }
}

代码解释:

  1. getDirectorySize(String directoryPath) 方法:
  2. 参数: directoryPath (String),要计算大小的目录路径。
  3. 返回值: long,目录下所有文件占用的总空间大小 (字节)。如果目录不存在或发生 IO 异常,返回 -1。
  4. 路径处理:
  5. java复制代码
  6. Path dirPath = Paths.get(directoryPath); if (!Files.exists(dirPath) || !Files.isDirectory(dirPath)) { System.err.println("Error: Directory not found or invalid path: " + directoryPath); return -1; }
  7. 使用 Paths.get(directoryPath) 将字符串路径转换为 Path 对象,这是 Java NIO.2 中用于表示文件和目录路径的接口。
  8. 使用 Files.exists(dirPath) 检查路径是否存在。
  9. 使用 Files.isDirectory(dirPath) 检查路径是否是目录。
  10. 如果路径不存在或不是目录,打印错误信息到 System.err (标准错误输出流),并返回 -1 表示错误。
  11. final long[] totalSize = {0};:创建一个 long 数组 totalSize,并初始化为 {0}。 关键点: 在 Java 8 之前 (以及在 Lambda 表达式和匿名内部类中访问外部变量时),外部变量需要是 final 或 effectively final (在初始化后不再修改)。 这里使用数组 long[] 是一个常用的 workaround,因为数组本身是 final 的 (数组引用不可变),但数组元素的值是可以修改的,这样我们就可以在 SimpleFileVisitor 的匿名内部类中修改 totalSize[0] 来累加文件大小。
  12. Files.walkFileTree(dirPath, new SimpleFileVisitor() { ... });:使用 Files.walkFileTree() 方法来遍历目录树。dirPath: 要遍历的起始目录的 Path 对象。new SimpleFileVisitor() { ... }: 创建一个匿名内部类,继承自 SimpleFileVisitor()。 SimpleFileVisitor 是 FileVisitor 接口的一个便捷实现,我们只需要重写我们感兴趣的方法。@Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { ... }:重写 visitFile() 方法。这个方法在遍历到每个文件时会被调用。totalSize[0] += attrs.size();: 使用 attrs.size() 获取当前文件的大小 (字节),并将其累加到 totalSize[0] 中。return FileVisitResult.CONTINUE;: 返回 FileVisitResult.CONTINUE,表示继续遍历目录树的下一个文件或目录。@Override public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException { ... }:重写 visitFileFailed() 方法。这个方法在访问文件失败时 (例如,权限不足) 会被调用。System.err.println("Failed to visit file: " + file + ", error: " + exc.getMessage());: 打印错误信息到 System.err,提示哪个文件访问失败以及错误原因。return FileVisitResult.CONTINUE;: 返回 FileVisitResult.CONTINUE,表示即使文件访问失败,也继续遍历目录树的其他部分。 如果希望在遇到错误时停止遍历,可以返回 FileVisitResult.TERMINATE。
  13. catch (IOException e) { ... }:捕获 Files.walkFileTree() 方法可能抛出的 IOException 异常,例如,如果目录遍历过程中发生 IO 错误。打印错误信息到 System.err,并返回 -1 表示发生 IO 异常。
  14. return totalSize[0];: 遍历完成后,返回 totalSize[0],即目录下所有文件大小的总和 (字节)。
  15. formatFileSize(long sizeBytes) 方法:
  16. 参数: sizeBytes (long),文件大小 (字节)。
  17. 返回值: String,格式化后的文件大小字符串,例如 “1.23 MB”。
  18. 单位转换: 将字节大小转换为更易读的单位 (KB, MB, GB, TB),根据大小选择合适的单位。
  19. 格式化输出: 使用 String.format("%.2f %s", size, unit) 将大小和单位格式化为字符串,保留两位小数。
  20. main(String[] args) 方法:
  21. String directoryToCalculate = "./";: 设置要计算大小的目录路径,这里设置为当前目录 ./。 你可以将其替换为任何有效的目录路径。
  22. long totalSizeBytes = getDirectorySize(directoryToCalculate);: 调用 getDirectorySize() 方法计算目录大小。
  23. 错误处理和输出:检查 totalSizeBytes 的返回值是否为 -1,如果是,则表示计算失败,打印错误信息。如果计算成功 (返回值不是 -1),调用 formatFileSize() 方法将字节大小格式化为易读的字符串,并打印格式化后的目录大小。
  24. 测试不存在的目录: 演示了如何测试一个不存在的目录,并验证 getDirectorySize() 方法能够正确处理这种情况并返回 -1。

如何运行代码:

用java方法编写计算指定目录下所有文件占空间大小

  1. 保存代码: 将代码保存为 DirectorySizeCalculator.java 文件。
  2. 编译代码: 在命令行或终端中,使用 javac DirectorySizeCalculator.java 命令编译 Java 文件。
  3. 运行代码: 使用 java DirectorySizeCalculator 命令运行编译后的程序。

程序会输出指定目录 (默认为当前目录 ./) 的总大小,并以易读的格式 (例如 “KB”, “MB”, “GB”) 显示。 你可以修改 directoryToCalculate 变量的值来计算其他目录的大小。

总结:

这段代码使用了 Java NIO.2 API 中的 Files.walkFileTree() 方法和 SimpleFileVisitor 类,高效地遍历目录树,并计算目录下所有文件的总大小。 代码结构清晰,包含了错误处理,并且提供了将字节大小格式化为易读单位的功能,是一个实用的计算目录大小的 Java 方法。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表