fileoutputstream 本身不提供截断文件的方法,但可通过其关联的 filechannel 调用 truncate() 实现:需以写入模式构造流(如 new fileoutputstream(file)),调用 getchannel() 获取通道,再执行 channel.truncate(size)——size 小于当前长度则丢弃末尾,大于等于则不变,负数抛 illegalargumentexception。

FileOutputStream 本身不提供截断文件的方法,但可以通过它获取关联的 FileChannel,再调用 truncate() 实现截断。
获取 FileChannel 的正确方式
必须在构造 FileOutputStream 时启用写入模式(不能只读),且推荐使用 getChannel() 获取通道:
- 使用
new FileOutputStream(file, true)(追加模式)或new FileOutputStream(file)(覆盖模式)均可获得可写的 FileChannel - 调用
fileOutputStream.getChannel()得到 FileChannel 实例 - 注意:如果 FileOutputStream 是以只读方式打开(实际不可行,因为 FileOutputStream 只支持写入),则 channel 不可写,truncate 会抛出 NonWritableChannelException
truncate() 的行为说明
truncate(long size) 将文件截断为指定字节长度:
- 若
size小于当前文件长度,末尾多余内容被丢弃 - 若
size大于等于当前长度,文件不变(不会填充或扩展) - 若
size为负数,抛出 IllegalArgumentException - 截断操作立即生效,无需 flush 或 close(但需确保 channel 未关闭)
完整示例代码
以下代码将文件截断为前 100 字节:
File file = new File("data.txt");
try (FileOutputStream fos = new FileOutputStream(file);
FileChannel channel = fos.getChannel()) {
channel.truncate(100); // 截断为 100 字节
} catch (IOException e) {
e.printStackTrace();
}
注意:try-with-resources 会自动关闭 FileOutputStream 和其关联的 channel,所以 truncate 必须在 channel 关闭前调用。
常见问题提醒
容易出错的地方:
- 在 close() 之后调用 truncate → 抛出 ClosedChannelException
- 用
new FileOutputStream(file, false)(默认就是 false)没问题,但别误用RandomAccessFile混淆逻辑 - 截断不影响 FileOutputStream 内部缓冲区,后续 write() 会从截断后的位置继续写入(即新内容会覆盖原位置)
- 多线程环境下,确保没有其他进程/线程同时写该文件,否则截断结果可能不可预期
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











