Is it overkill to use BufferedWriter and BufferedO

2019-02-13 10:40发布

I want to write to a socket. From reading about network IO, it seems to me that the optimal way to write to it is to do something like this:

OutputStream outs=null;
BufferedWriter out=null;
out =
  new BufferedWriter(
    new OutputStreamWriter(new BufferedOutputStream(outs),"UTF-8"));

The BufferedWriter would buffer the input to the OutputStreamWriter which is recommended, because it prevents the writer from starting up the encoder for each character.

The BufferedOutputStream would then buffer the bytes from the Writer to avoid putting one byte at a time potentially onto the network.

It looks a bit like overkill, but it all seems like it helps? Grateful for any help..

EDIT: From the javadoc on OutputStreamWriter:

Each invocation of a write() method causes the encoding converter to be invoked on the given character(s). The resulting bytes are accumulated in a buffer before being written to the underlying output stream. The size of this buffer may be specified, but by default it is large enough for most purposes. Note that the characters passed to the write() methods are not buffered.

For top efficiency, consider wrapping an OutputStreamWriter within a BufferedWriter so as to avoid frequent converter invocations. For example:

Writer out = new BufferedWriter(new OutputStreamWriter(System.out));

3条回答
The star\"
2楼-- · 2019-02-13 11:10

The BufferedWriter would buffer the input to the outputStreamWriter, which is recommended because it prevents the writer from starting up the encoder for each character.

Recommended by who, and in what context? What do you mean by "starting up the encoder"? Are you writing a single character at a time to the writer anyway? (We don't know much about how you're using the writer... that could be important.)

The BufferedOutputStream would then buffer the bytes from the Writer to avoid putting one byte at a time potentially onto the network.

What makes you think it would write one byte at a time? I think it very unlikely that OutputStreamWriter will write a byte at a time to the underlying writer, unless you really write a character at a time to it.

Additionally, I'd expect the network output stream to use something like Nagle's algorithm to avoid sending single-byte packets.

As ever with optimization, you should do it based on evidence... have you done any testing with and without these layers of buffering?

EDIT: Just to clarify, I'm not saying the buffering classes are useless. In some cases they're absolutely the right way to go. I'm just saying that as with all optimization, they shouldn't be used blindly. You should consider what you're trying to optimize for (processor usage, memory usage, network usage etc) and measure. There are many factors which matter here - not least of which is the write pattern. If you're already writing "chunkily" - writing large blocks of character data - then the buffers will have relatively little impact. If you're actually writing a single character at a time to the writer, then they would be more significant.

查看更多
forever°为你锁心
3楼-- · 2019-02-13 11:14

The purpose of the Buffered* classes is to coalesce small write operations into a larger one, thereby reducing the number of system calls, and increasing throughput.

Since a BufferedWriter already collects writes in a buffer, then converts the characters in the buffer into another buffer, and writes that buffer to the underlying OutputStream in a single operation, the OutputStream is already invoked with large write operations. Therefore, a BufferedOutputStream finds nothing to combine, and is simply redundant.

As an aside, the same can apply to the BufferedWriter: buffering will only help if the writer is only passed few characters at a time. If you know the caller only writes huge strings, the BufferedWriter will find nothing to combine and is redundant, too.

查看更多
乱世女痞
4楼-- · 2019-02-13 11:16

Yes it is overkill. From the Javadoc for OutputStreamWriter: "Each invocation of a write() method causes the encoding converter to be invoked on the given character(s). The resulting bytes are accumulated in a buffer before being written to the underlying output stream.".

查看更多
登录 后发表回答