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(需反射访问,生产环境慎用)
写入前主动检查可用空间
比被动捕获更可靠,适用于关键写入操作:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 使用
FileStore.getUsableSpace()获取目标路径所在文件系统的剩余字节数 - 预估待写入数据大小(如文件大小、缓冲区容量),留出安全余量(例如 +10% 或至少 1MB)
- 示例:
long usable = Files.getFileStore(Paths.get("/data/output.txt")).getUsableSpace(); if (usable
写入中处理 IOException 的健壮策略
即使提前检查,仍可能因并发写入、日志轮转等导致瞬时空间不足:
- 对
FileOutputStream写入操作做 try-catch,区分处理:记录详细日志(含路径、预期大小、当前可用空间)、触发告警、清理临时文件或归档旧日志 - 避免静默吞掉异常;不要简单重试(除非确认空间已释放),否则可能反复失败并阻塞线程
- 考虑降级:如切换到备用存储路径(另一磁盘)、写入内存缓冲后异步落盘、或转存为压缩格式减小体积
运维层面的预防建议
从系统角度降低发生概率:
- 监控磁盘使用率(如 Prometheus + Node Exporter),阈值设为 85%~90%,提前告警
- 配置日志滚动策略(如 Logback 的
TimeBasedRollingPolicy+FixedWindowRollingPolicy),限制总大小和保留天数 - 定期清理无用临时文件、core dump、缓存目录(可结合
find /tmp -type f -mtime +7 -delete等脚本)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










