newOutputStream 并非真正执行写入操作,而是明确拒绝写入请求——它通过静态辅助方法 readOnly() 抛出 ReadOnlyFileSystemException,以强制体现 JRT 文件系统的只读本质。
`newoutputstream` 并非真正执行写入操作,而是明确拒绝写入请求——它通过静态辅助方法 `readonly()` 抛出 `readonlyfilesystemexception`,以强制体现 jrt 文件系统的只读本质。
在 Java 标准库中,java.nio.file.FileSystem 接口定义了 newOutputStream(Path, OpenOption...) 方法,作为文件系统提供者(如 JrtFileSystem)实现的核心契约之一。该方法本应返回一个可写入的 OutputStream 实例,但针对 JRT(Java Runtime Image)文件系统——即通过 jrt:/ URI 访问的模块化运行时镜像(如 java.base 模块中的类与资源)——其设计原则是严格只读:运行时镜像由 JVM 静态构建并内存映射,禁止任何修改。
因此,jdk.internal.jrtfs.JrtFileSystem 的 newOutputStream 方法实现如下:
final OutputStream newOutputStream(JrtPath jrtPath, OpenOption... options) throws IOException {
throw readOnly(); // ← 关键逻辑
}此处 readOnly() 是一个私有静态工具方法:
static ReadOnlyFileSystemException readOnly() {
return new ReadOnlyFileSystemException();
}这等价于直接写为:
立即学习“Java免费学习笔记(深入)”;
throw new ReadOnlyFileSystemException();
ReadOnlyFileSystemException 是 IOException 的子类,专用于标识“尝试对只读文件系统执行写操作”的语义错误。JVM 在调用 Files.newOutputStream(Paths.get("jrt:/java.base/java/lang/Object.class")) 时,底层会委托至 JrtFileSystem,立即触发该异常,而非进入实际 I/O 流创建流程。
✅ 关键点总结:
- newOutputStream 在 JrtFileSystem 中不创建流对象,也不打开文件句柄,纯粹是语义拦截;
- 异常抛出是主动、即时、确定性的设计选择,避免资源分配或状态误判;
- 此机制符合 FileSystem SPI 规范:实现类可依据自身语义自由决定 OpenOption 支持范围(如 StandardOpenOption.WRITE 在 JRT 中永远不被接受);
- 开发者应通过 try-catch 显式捕获 ReadOnlyFileSystemException,或在调用前通过 isReadOnly() 判断文件系统属性(jrtfs 始终返回 true)。
值得注意的是,这一设计与 FileOutputStream 形成鲜明对比:后者面向真实磁盘文件,支持追加、覆盖、通道获取等完整写入能力;而 JrtFileSystem.newOutputStream 则代表一种“契约式防御”——用最轻量的方式宣告边界,确保模块化运行时的完整性与安全性。这也体现了 Java NIO.2 文件系统抽象的强大扩展性:同一接口下,可承载从本地磁盘、内存文件系统(MemoryFileSystem)、ZIP 文件系统到只读运行时镜像等截然不同的实现语义。


















