OutputStreamWriter 的编码行为由关联 Charset 的默认 encoder 决定;需自定义错误策略时,应通过 Charset.newEncoder() 设置 CodingErrorAction 并手动编码,或包装 OutputStream 拦截异常,而非依赖 OutputStreamWriter 直接配置。

OutputStreamWriter 本身不直接暴露 CharsetEncoder 的配置接口,但可以通过构造时传入的 Charset 或 CharsetEncoder 实例间接控制编码失败行为。
使用带替换策略的 Charset 构造
最常用方式是通过 Charset.forName("UTF-8").newEncoder() 获取编码器,设置其 malformed input 和 unmappable character 处理策略,再包装成 Charset(需借助 CharsetEncoder + Charset 自定义实现较复杂),更推荐直接用 StandardCharsets 配合 CharsetEncoder 的替代方案:
- 调用
Charset.forName("UTF-8").newEncoder().onUnmappableCharacter(CodingErrorAction.REPLACE) - 但注意:OutputStreamWriter 不接受 encoder,只接受 Charset 或 String 名称
- 因此实际生效的是 Charset 默认的 encoder 行为 —— 多数标准 Charset(如 UTF-8、ISO-8859-1)默认对不可映射字符抛 CharacterCodingException
用 OutputStreamWriter + 自定义 OutputStream 包装异常
若需统一处理(如替换成 ? 或忽略),可在底层 OutputStream 层拦截异常:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 继承 FilterOutputStream,重写
write(byte[], int, int) - 捕获 CharacterCodingException(由内部 encoder 抛出)
- 在 catch 块中写入替代字节(如 UTF-8 中
0xEF 0xBF 0xBD表示 )或跳过 - 再用该 stream 构造 OutputStreamWriter
改用 BufferedWriter + 手动编码(更可控)
绕过 OutputStreamWriter 的自动编码,自己控制编码流程:
立即学习“Java免费学习笔记(深入)”;
- 用
CharsetEncoder encoder = StandardCharsets.UTF_8.newEncoder() - 调用
encoder.onUnmappableCharacter(CodingErrorAction.REPLACE) - 对每个字符串调用
encoder.encode(CharBuffer.wrap(str))得到 ByteBuffer - 将 byte buffer 写入底层 OutputStream
- 配合 BufferedWriter 缓冲写入,避免频繁 flush
推荐做法:优先用 String.getBytes() + try-catch
简单场景下,不必强依赖 OutputStreamWriter 的编码器配置:
- 对要写入的字符串调用
str.getBytes(StandardCharsets.UTF_8) - 该方法内部使用默认 encoder,遇到不可映射字符会抛 UnsupportedEncodingException(实际不会,UTF-8 支持所有 Unicode)
- 但若用
str.getBytes("ISO-8859-1"),则超出范围字符会被静默截断或替换(取决于 JVM 实现) - 更稳妥:用
StandardCharsets.UTF_8.newEncoder().encode(CharBuffer.wrap(str))显式控制

















