Java中FileOutputStream写入失败时,若磁盘空间不足,JVM抛出IOException而非自定义异常;可通过异常消息字符串(如“No space left on device”)或Unix平台下反射获取sun.nio.fs.UnixException的errno=28粗略识别;更可靠做法是写入前调用Files.getFileStore().getUsableSpace()主动校验剩余空间并预留余量。

Java 中 FileOutputStream 在磁盘写入失败时,若底层操作系统返回“No space left on device”错误(对应 Linux/Unix 的 ENOSPC),JVM 会将其封装为 IOException 抛出——不会专门抛出 NoSpaceLeftException 这类自定义异常,因此需通过检查异常信息或 errno(间接)识别该场景。
捕获并识别磁盘空间不足异常
虽然 Java 标准库不暴露原生 errno,但可通过异常消息字符串粗略判断(注意:不跨平台、不可靠但常用):
- Linux/macOS 下,
IOException的getMessage()常含"No space left on device"或"Disk quota exceeded" - Windows 下可能表现为
"The disk is full"或"There is not enough space on the disk",但更常见的是IOException无明确提示,需结合Files.getFileStore(path).getUsableSpace()提前校验 - 推荐做法:捕获
IOException后,用getCause()检查是否为sun.nio.fs.UnixException(仅 Unix 平台),其内部持有 errno,值为 28 即ENOSPC(需反射访问,生产环境慎用)
写入前主动检查可用空间
比被动捕获更可靠,适用于关键写入操作:
- 使用
FileStore.getUsableSpace()获取目标路径所在文件系统的剩余字节数 - 预估待写入数据大小(如文件大小、缓冲区容量),留出安全余量(例如 +10% 或至少 1MB)
- 示例:
long usable = Files.getFileStore(Paths.get("/data/output.txt")).getUsableSpace(); if (usable
写入中处理 IOException 的健壮策略
即使提前检查,仍可能因并发写入、日志轮转等导致瞬时空间不足:
立即学习“Java免费学习笔记(深入)”;
- 对
FileOutputStream写入操作做 try-catch,区分处理:记录详细日志(含路径、预期大小、当前可用空间)、触发告警、清理临时文件或归档旧日志 - 避免静默吞掉异常;不要简单重试(除非确认空间已释放),否则可能反复失败并阻塞线程
- 考虑降级:如切换到备用存储路径(另一磁盘)、写入内存缓冲后异步落盘、或转存为压缩格式减小体积
运维层面的预防建议
从系统角度降低发生概率:
- 监控磁盘使用率(如 Prometheus + Node Exporter),阈值设为 85%~90%,提前告警
- 配置日志滚动策略(如 Logback 的
TimeBasedRollingPolicy+FixedWindowRollingPolicy),限制总大小和保留天数 - 定期清理无用临时文件、core dump、缓存目录(可结合
find /tmp -type f -mtime +7 -delete等脚本)


















