在Java开发中,获取文件或文件夹的大小是一个常见的需求,例如磁盘空间管理、日志分析、系统监控等场景,本文将详细介绍如何使用Java获取当前文件或文件夹的大小,涵盖基础方法、递归计算、NIO工具类以及注意事项,帮助开发者全面掌握相关技术。

获取单个文件的大小
在Java中,获取单个文件的大小最直接的方式是使用java.io.File类的length()方法,该方法返回文件的大小,单位为字节(byte),返回值为long类型,能够支持大文件(超过2GB)的存储。
示例代码
import java.io.File;
public class FileSizeExample {
public static void main(String[] args) {
File file = new File("example.txt"); // 替换为实际文件路径
if (file.exists() && file.isFile()) {
long fileSize = file.length();
System.out.println("文件大小: " + fileSize + " 字节");
// 可选:转换为更易读的单位(KB、MB、GB)
System.out.println("文件大小: " + formatFileSize(fileSize));
} else {
System.out.println("文件不存在或不是普通文件");
}
}
// 格式化文件大小(字节转换为KB/MB/GB)
private static String formatFileSize(long size) {
if (size < 1024) {
return size + " B";
} else if (size < 1024 * 1024) {
return String.format("%.2f KB", size / 1024.0);
} else if (size < 1024 * 1024 * 1024) {
return String.format("%.2f MB", size / (1024.0 * 1024));
} else {
return String.format("%.2f GB", size / (1024.0 * 1024 * 1024));
}
}
}
说明
file.exists():检查文件是否存在,避免因文件不存在抛出异常。file.isFile():确保目标对象是普通文件而非文件夹。length()方法:如果文件不存在,返回0;如果是文件夹,返回的是文件夹本身的大小(通常为0,不包含子文件和子文件夹)。
计算文件夹的总大小
文件夹的大小是其包含的所有文件和子文件夹大小的总和,计算文件夹大小需要遍历其内部的所有文件和子文件夹,递归累加每个文件的大小,以下是两种实现方式:递归遍历和Java NIO的Files.walk方法。
递归方式计算文件夹大小
递归方式通过File类的listFiles()方法获取文件夹下的所有文件和子文件夹,如果是文件则直接累加大小,如果是子文件夹则递归调用计算方法。
示例代码
import java.io.File;
public class FolderSizeRecursive {
public static void main(String[] args) {
File folder = new File("example_folder"); // 替换为实际文件夹路径
if (folder.exists() && folder.isDirectory()) {
long folderSize = calculateFolderSize(folder);
System.out.println("文件夹总大小: " + folderSize + " 字节");
System.out.println("文件夹总大小: " + formatFileSize(folderSize));
} else {
System.out.println("路径不存在或不是文件夹");
}
}
// 递归计算文件夹大小
private static long calculateFolderSize(File folder) {
long size = 0;
File[] files = folder.listFiles();
if (files == null) {
return 0; // 无权限访问或文件夹为空
}
for (File file : files) {
if (file.isFile()) {
size += file.length();
} else if (file.isDirectory()) {
size += calculateFolderSize(file); // 递归调用子文件夹
}
}
return size;
}
// 复用上文formatFileSize方法
private static String formatFileSize(long size) { /* 同上 */ }
}
说明
listFiles():返回文件夹下的所有文件和子文件夹数组,如果文件夹为空或无访问权限,返回null。- 递归终止条件:当遍历到普通文件时,直接累加大小;当遍历到子文件夹时,递归调用直至所有文件被处理。
- 缺点:对于深层嵌套的文件夹,递归可能导致栈溢出(
StackOverflowError),需注意文件夹层级深度。
使用Java NIO的Files.walk计算文件夹大小
Java 7引入了java.nio.file包,提供了更现代化的文件操作方式。Files.walk()方法可以生成一个Stream<Path>,遍历文件树中的所有文件,支持并行处理,适合大文件夹或深层嵌套文件夹的场景。
示例代码
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class FolderSizeNIO {
public static void main(String[] args) {
Path folderPath = Paths.get("example_folder"); // 替换为实际文件夹路径
if (Files.exists(folderPath) && Files.isDirectory(folderPath)) {
try {
long folderSize = Files.walk(folderPath)
.filter(Files::isRegularFile) // 只统计普通文件,跳过文件夹
.mapToLong(path -> {
try {
return Files.size(path);
} catch (IOException e) {
System.err.println("无法获取文件大小: " + path);
return 0;
}
})
.sum();
System.out.println("文件夹总大小: " + folderSize + " 字节");
System.out.println("文件夹总大小: " + formatFileSize(folderSize));
} catch (IOException e) {
System.err.println("遍历文件夹时出错: " + e.getMessage());
}
} else {
System.out.println("路径不存在或不是文件夹");
}
}
// 复用上文formatFileSize方法
private static String formatFileSize(long size) { /* 同上 */ }
}
说明
Files.walk(path):从指定路径开始递归遍历文件树,生成Path流。filter(Files::isRegularFile):过滤掉子文件夹,只保留普通文件。mapToLong(Files::size):将每个文件路径映射为其大小,Files.size(path)等效于File.length()。sum():对文件大小求和。- 优点:代码简洁,支持并行流(
.parallel()提高大文件遍历效率),避免手动递归的栈溢出风险。
注意事项与异常处理
在获取文件或文件夹大小时,需注意以下常见问题及异常处理:

文件/文件夹不存在
File.length()和Files.size()在文件不存在时行为不同:
File.length():返回0,不会抛出异常。Files.size():抛出NoSuchFileException。
建议操作前通过exists()或Files.exists()检查路径是否存在。
文件权限问题
如果程序没有读取文件的权限,会抛出SecurityException(File类)或AccessDeniedException(NIO),需捕获异常并处理,
try {
long size = Files.size(path);
} catch (AccessDeniedException e) {
System.err.println("无权限访问文件: " + path);
} catch (IOException e) {
System.err.println("读取文件出错: " + e.getMessage());
}
符号链接(软链接)处理
符号链接可能指向循环路径(如A链接到B,B链接到A),导致无限递归,可通过Files.isSymbolicLink(path)判断是否为符号链接,并决定是否跳过或解析:
Files.walk(path)
.filter(p -> !Files.isSymbolicLink(p)) // 跳过符号链接
// 或解析符号链接:Files.readSymbolicLink(p)
大文件与long类型范围
length()和Files.size()返回long类型,最大值为2^63-1(约8EB),对于当前文件系统已足够,无需额外处理。
代码示例与实现小编总结
以下是综合递归和NIO方法的完整示例,可根据实际需求选择:

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class FileSizeDemo {
public static void main(String[] args) {
String filePath = "test.txt";
String folderPath = "test_folder";
// 获取文件大小
printFileSize(filePath);
// 获取文件夹大小(递归)
printFolderSizeRecursive(folderPath);
// 获取文件夹大小(NIO)
printFolderSizeNIO(folderPath);
}
// 打印文件大小
private static void printFileSize(String path) {
File file = new File(path);
if (file.isFile()) {
System.out.println("文件 [" + path + "] 大小: " + formatFileSize(file.length()));
} else {
System.out.println("文件不存在或不是普通文件: " + path);
}
}
// 打印文件夹大小(递归)
private static void printFolderSizeRecursive(String path) {
File folder = new File(path);
if (folder.isDirectory()) {
long size = calculateFolderSize(folder);
System.out.println("文件夹 [" + path + "] 大小(递归): " + formatFileSize(size));
} else {
System.out.println("路径不存在或不是文件夹: " + path);
}
}
// 打印文件夹大小(NIO)
private static void printFolderSizeNIO(String path) {
Path folder = Paths.get(path);
if (Files.isDirectory(folder)) {
try {
long size = Files.walk(folder)
.filter(Files::isRegularFile)
.mapToLong(p -> {
try { return Files.size(p); }
catch (IOException e) { return 0; }
})
.sum();
System.out.println("文件夹 [" + path + "] 大小(NIO): " + formatFileSize(size));
} catch (IOException e) {
System.err.println("NIO遍历文件夹出错: " + e.getMessage());
}
} else {
System.out.println("路径不存在或不是文件夹: " + path);
}
}
// 格式化文件大小
private static String formatFileSize(long size) {
if (size < 1024) return size + " B";
if (size < 1024 * 1024) return String.format("%.2f KB", size / 1024.0);
if (size < 1024 * 1024 * 1024) return String.format("%.2f MB", size / (1024.0 * 1024));
return String.format("%.2f GB", size / (1024.0 * 1024 * 1024));
}
// 递归计算文件夹大小
private static long calculateFolderSize(File folder) {
long size = 0;
File[] files = folder.listFiles();
if (files != null) {
for (File file : files) {
size += file.isFile() ? file.length() : calculateFolderSize(file);
}
}
return size;
}
}
获取Java中文件或文件夹大小的方法主要有两种:
- 传统
File类:通过length()获取文件大小,递归遍历计算文件夹大小,适合简单场景,但需注意递归深度问题。 - NIO的
Files.walk():利用流式API遍历文件树,支持并行处理,代码更简洁,适合大文件或复杂文件夹结构。
实际开发中,需根据文件大小、层级深度和性能需求选择合适的方法,同时注意异常处理(权限、符号链接、路径不存在等),通过合理封装工具方法,可以高效复用文件大小计算逻辑,提升开发效率。















