【发布时间】:2016-04-23 10:51:08
【问题描述】:
我需要将char 的流转换为bytes 的流,即我需要一个从java.io.Writer 接口到java.io.OutputStream 的适配器,它支持我将拥有的任何有效Charset一个配置参数。
但是,java.io.OutputStreamWriter 类有一个隐藏的秘密:它委托给下面的 sun.nio.cs.StreamEncoder 对象会创建一个 8192 字节 (8KB) 的缓冲区,即使您没有要求它也是如此。
问题是,在OutputStream 端,我插入了一个包装器,该包装器需要计算正在写入的字节数,以便在达到特定数量后立即停止源系统的执行已输出字节数。如果OutputStreamWriter 正在创建一个 8K 缓冲区,我只会收到生成的字节量的通知为时已晚,因为它们只会在缓冲区刷新时到达我的计数器(因此在OutputStreamWriter 缓冲区中已经有超过 8,000 个已生成的字节在等待我)。
所以问题是,Java 运行时中是否有 Writer -> OutputStream 可以无缓冲运行的网桥?
我真的非常讨厌自己写这个:(...
注意:每次写入都在OutputStreamWriter 上点击flush() 不是有效的替代方法。这会带来很大的性能损失(StreamEncoder 涉及一个 synchronized 块)。
注意 2:我知道可能有必要在桥上保留一个小的 char 溢出以便计算代理项。并不是说我需要在源系统生成第 n 个字节的那一刻停止执行源系统(这是不可能的,因为字节可以以更大的 byte[] 的形式出现在 write 中称呼)。但是我需要尽快停止它,而等待 8K、2K 甚至 200 字节的缓冲区刷新就太迟了。
【问题讨论】:
-
可以说它不能完全无缓冲 - 如果您只使用代理对的前半部分调用
write,对于大多数编码,作者将拥有 存储它并在写任何东西之前等待第二个字符。 -
嗯,是的,当然,我明白这一点。但是计算代理对和 8K 缓冲区所需的几个缓冲字符之间存在差异......
-
我认为那里没有任何“当然” - 我怀疑许多读者会认为您的意思是根本没有缓冲,并且您可能不知道代理对。我建议您编辑问题以澄清这一点。 (例如,如果第一次调用
write没有停止执行,会不会“为时已晚”?)
标签: java buffer outputstream writer