是否存在不带缓冲的 OutputStreamWriter?

Does an OutputStreamWriter without buffering exist?

我需要将 char 的流转换为 byte 的流,即我需要一个从 java.io.Writer 接口到 java.io.OutputStream 的适配器,支持我将作为配置参数的任何有效 Charset

然而,java.io.OutputStreamWriter class 有一个隐藏的秘密:它在下面委托的 sun.nio.cs.StreamEncoder 对象会创建一个 8192 字节 (8KB) 的缓冲区,即使您不询问

问题是,在 OutputStream 末尾,我插入了一个包装器,需要 计算正在写入的字节数 ,以便它立即停止执行输出特定数量的字节后,源系统。如果 OutputStreamWriter 正在创建一个 8K 缓冲区,我只是收到生成的字节数的通知 太晚了 因为它们只会在缓冲区为 [=41= 时到达我的计数器]flushing(所以已经有超过 8,000 个已经生成的字节在 OutputStreamWriter 缓冲区等着我)。

所以问题是,在 Java 运行 时间的任何地方有 Writer -> OutputStream 桥可以 运行 无缓冲?

我真的非常讨厌自己写这个:(...

注意:每次写入时在 OutputStreamWriter 上点击 flush() 不是有效的替代方法。这会带来很大的性能损失(在 StreamEncoder 处涉及一个 synchronized 块)。

注意 2:我知道可能有必要在桥上保留一个小的字符溢出以计算代理项。这并不是说我需要在它生成第 n 个字节的那一刻停止源系统的执行(这是不可能的,因为字节可以以更大的 byte[] 的形式出现在 write调用)。但我需要尽快停止它,等待 8K、2K 甚至 200 字节的缓冲区刷新就太晚了。

正如您已经检测到 OutputStreamWriter 使用的 StreamEncoder 的缓冲区大小为 8KB,并且没有更改该大小的界面。

但以下代码片段为您提供了一种获取 OutputStreamWriter 的方法,它在内部也使用 StreamEncoder 但现在具有用户定义的缓冲区大小:

String charSetName = ...
CharsetEncoder encoder = Charset.forName(charSetName).newEncoder();

OutputStream out = ...
int bufferSize = ...

WritableByteChannel channel = Channels.newChannel(out);
Writer writer = Channels.newWriter(channel, encoder, bufferSize);