Files.size() 本身不会溢出,它返回精确的long类型文件大小;常见“溢出”实为后续转int/float、格式化错误或系统不支持导致;应全程用long、加异常处理、避免隐式降级。

Files.size() 返回的是 long 类型,正常情况下能表示最大约 9.2 × 10¹⁸ 字节(即约 8 EB),远超绝大多数实际文件。所谓“数值溢出”在调用 Files.size() 本身时不会发生——它底层调用操作系统 stat 系统调用,Java 的 Files.size() 已对结果做了安全封装,返回值就是文件的准确字节大小(只要系统能正确报告)。
为什么你可能误以为“溢出”了?
常见误解来源不是 Files.size() 本身,而是后续处理环节:
-
转成 int 或 float/double 时截断或精度丢失:比如
(int) Files.size(path),当文件 > 2GB 就溢出;或用float存储 TB 级文件,有效位数不足导致末几位字节丢失。 -
字符串拼接或日志打印时用了错误格式:例如用
%d格式化 long 值却传入 int 变量,或在 32 位环境误判 long 表示范围。 -
文件系统或 OS 层面限制导致 size 返回 0 或负值:某些特殊文件(如 /proc 下的伪文件、FIFO、设备文件)不支持获取大小,Files.size() 会抛出
IOException;极少数旧系统或挂载选项下可能返回 -1(但 Java NIO 通常转为异常而非返回负数)。
安全获取与使用文件大小的推荐做法
保持 long 类型全程使用,避免隐式降级:
- 声明变量用
long fileSize = Files.size(path);,不要强转。 - 比较时直接用 long 常量:
if (fileSize > 10L * 1024 * 1024 * 1024)(10 GB)。 - 格式化输出用
String.format("%,d", fileSize)或NumberFormat,确保 long 正确显示。 - 记录日志推荐 SLF4J 的占位符:
log.info("File size: {} bytes", fileSize);(自动适配 long)。
大文件场景下的实用补充建议
单纯知道大小还不够,处理大文件需配套策略:
-
先检查可读性与权限:用
Files.isReadable(path) && Files.isRegularFile(path)避免对目录或无权文件调用 size() 报错。 -
加 try-catch 处理异常:size() 可能抛
IOException(如文件被删除、权限突变、网络文件系统超时),不应假设一定成功。 - 需要分块处理时,别依赖 size() 做唯一依据:对于可变长度编码(如 UTF-8 文本)、压缩流或加密容器,字节大小 ≠ 逻辑内容大小,应结合业务需求选择读取方式(如按行、按缓冲区、用流式解析器)。
Files.size() 本身健壮可靠,真正要防范的是后续类型误用和边界异常。保持类型一致、显式处理异常、按需选择读取策略,就能稳妥应对从 KB 到 TB 级别的文件。

















