在Java开发中,获取文件大小是一项常见的基础操作,广泛应用于文件上传、下载校验、存储管理、日志分析等场景,无论是判断文件是否超出限制、计算目录总容量,还是在数据处理中预估耗时,准确获取文件大小都是关键前提,本文将详细介绍Java中获取文件大小的多种方法,涵盖传统IO与NIO.2两种技术体系,并结合代码示例、异常处理及性能对比,帮助开发者根据实际场景选择最优方案。

传统File类的length()方法
Java早期版本提供了java.io.File类,其length()方法是最直接的文件大小获取方式,该方法返回long类型值,表示文件以字节为单位的大小,若文件不存在或为目录,则返回0。
核心用法:
import java.io.File;
public class FileSizeExample {
public static void main(String[] args) {
File file = new File("example.txt");
long sizeInBytes = file.length();
// 转换为更易读的单位
System.out.println("文件大小(字节): " + sizeInBytes);
System.out.println("文件大小(KB): " + sizeInBytes / 1024.0);
System.out.println("文件大小(MB): " + sizeInBytes / (1024.0 * 1024.0));
}
}
注意事项:
- 文件不存在:若路径指向的文件不存在,
length()返回0,需结合exists()方法判断文件是否存在:if (file.exists()) { long size = file.length(); } else { System.err.println("文件不存在"); } - 目录处理:
length()对目录返回0,若需获取目录大小,需递归遍历目录下的所有文件并累加大小(后续会扩展)。 - 权限限制:若程序对文件无读取权限,可能抛出
SecurityException,需在安全管理器中处理。
NIO.2的Files.size()方法(Java 7+)
Java 7引入了NIO.2(New I/O 2),通过java.nio.file.Files和java.nio.file.Path提供了更现代、更灵活的文件操作方式。Files.size(Path path)是获取文件大小的核心方法,相比传统File类,它支持更丰富的路径处理和异常抛出机制。
核心用法:

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.io.IOException;
public class NioFileSizeExample {
public static void main(String[] args) {
Path path = Paths.get("example.txt");
try {
long sizeInBytes = Files.size(path);
System.out.println("文件大小(字节): " + sizeInBytes);
System.out.println("文件大小(GB): " + sizeInBytes / (1024.0 * 1024.0 * 1024.0));
} catch (IOException e) {
System.err.println("获取文件大小失败: " + e.getMessage());
}
}
}
优势与异常处理:
- 更精确的异常反馈:
Files.size()会抛出具体的受检异常,包括:NoSuchFileException:文件不存在;AccessDeniedException:无访问权限;IOException:其他IO错误(如磁盘损坏)。
通过捕获特定异常,可针对性处理不同场景,try { long size = Files.size(path); } catch (NoSuchFileException e) { System.err.println("文件路径错误: " + path); } catch (AccessDeniedException e) { System.err.println("无权限访问文件: " + path); }
- 符号链接支持:通过
Files.readAttributes()可获取符号链接的真实文件大小或链接本身大小,BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS); long size = attrs.size(); // 不跟随符号链接,获取链接本身大小
目录大小统计与递归处理
实际开发中,常需计算目录下所有文件的总大小(如磁盘空间分析),此时需递归遍历目录,累加每个文件的大小,无论是传统File还是NIO.2,均可实现递归统计,但NIO.2的Files.walk()方法更简洁高效。
NIO.2递归统计目录大小示例:
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Stream;
public class DirectorySizeCalculator {
public static void main(String[] args) {
Path dirPath = Paths.get("target/directory");
try {
long totalSize = calculateDirectorySize(dirPath);
System.out.println("目录总大小(MB): " + totalSize / (1024.0 * 1024.0));
} catch (IOException e) {
System.err.println("计算目录大小失败: " + e.getMessage());
}
}
public static long calculateDirectorySize(Path dirPath) throws IOException {
try (Stream<Path> paths = Files.walk(dirPath)) {
return paths
.filter(Files::isRegularFile) // 只统计普通文件
.mapToLong(path -> {
try {
return Files.size(path);
} catch (IOException e) {
return 0L; // 跳过无法访问的文件
}
})
.sum();
}
}
}
传统File递归示例:
public static long calculateDirectorySize(File dir) {
long size = 0;
File[] files = dir.listFiles();
if (files != null) {
for (File file : files) {
if (file.isFile()) {
size += file.length();
} else if (file.isDirectory()) {
size += calculateDirectorySize(file); // 递归
}
}
}
return size;
}
对比:NIO.2的Files.walk()基于流式处理,代码更简洁,且支持并行流(parallel())提升大目录统计效率;传统递归需手动处理空目录和异常,代码稍显冗长。

性能对比与场景选择
传统File.length()和NIO.2的Files.size()在性能上差异较小,均依赖底层系统调用,但NIO.2在以下场景更具优势:
- 复杂路径处理:
Paths.get()支持灵活的路径拼接(如Paths.get("parent", "child.txt")),而File需手动处理分隔符(或\)。 - 批量操作:NIO.2的
Files.walk()、Files.list()等方法适合批量处理文件,结合流式API可减少代码量。 - 元数据获取:若需同时获取文件大小、创建时间、修改时间等信息,
Files.readAttributes()比多次调用File.length()等方法更高效。
场景建议:
- 简单的单文件大小获取:优先使用
File.length()(代码简单,兼容性好); - 需要精确异常处理、路径操作或批量处理:选择NIO.2的
Files.size(); - 目录统计:推荐NIO.2的
Files.walk()(支持并行流,性能更优)。
注意事项与最佳实践
- 并发场景:若文件正在写入,获取的大小可能不完整,可通过文件锁(
FileChannel.lock())或业务逻辑(如校验文件是否被占用)确保数据一致性。 - 大文件处理:
long类型最大支持9223372036854775807字节(约8EB),远超普通文件大小,无需担心溢出问题。 - 资源释放:使用NIO.2的
Files.walk()时,需通过try-with-resources关闭流,避免资源泄漏。 - 跨平台兼容性:
Path和Files类已处理不同操作系统的路径分隔符差异,无需额外适配。
获取文件大小是Java文件操作的基础技能,掌握传统IO与NIO.2的方法,并结合场景选择合适的技术,能提升代码的健壮性与可维护性,无论是简单的文件校验,还是复杂的存储管理,准确获取文件大小都是保障系统稳定运行的重要环节。














