我想写一个套接字。从阅读网络IO,在我看来,写入它的最佳方式是做这样的事情:
OutputStream outs=null;
BufferedWriter out=null;
out =
new BufferedWriter(
new OutputStreamWriter(new BufferedOutputStream(outs),"UTF-8"));
BufferedWriter
会缓冲建议的OutputStreamWriter
输入,因为它会阻止编写器为每个字符启动编码器。
然后BufferedOutputStream
将缓冲来自Writer
的字节,以避免一次将一个字节放到网络上。
它看起来有点像矫枉过正,但它似乎都有帮助吗? 感谢任何帮助......
编辑:来自OutputStreamWriter
上的javadoc:
每次调用write()方法都会导致在给定字符上调用编码转换器。生成的字节在写入底层输出流之前累积在缓冲区中。可以指定此缓冲区的大小,但默认情况下,它足够大,可用于大多数用途。请注意,传递给write()方法的字符不会被缓冲。
为了获得最高效率,请考虑在BufferedWriter中包装OutputStreamWriter,以避免频繁的转换器调用。例如:
Writer out = new BufferedWriter(new OutputStreamWriter(System.out));
答案 0 :(得分:7)
Buffered *类的目的是将小写操作合并为一个更大的操作,从而减少系统调用次数,并提高吞吐量。
由于BufferedWriter已经在缓冲区中收集写入,然后将缓冲区中的字符转换为另一个缓冲区,并在单个操作中将该缓冲区写入底层的OutputStream,OutputStream已经通过大写操作调用。因此,BufferedOutputStream找不到任何要合并的东西,而且只是多余的。
顺便说一句,同样适用于BufferedWriter:缓冲只有在编写器一次只传递几个字符时才有用。如果你知道调用者只写了很大的字符串,那么BufferedWriter就会发现什么都没有结合起来也是多余的。
答案 1 :(得分:1)
BufferedWriter会缓冲outputStreamWriter的输入,建议使用它,因为它会阻止编写器为每个字符启动编码器。
由谁推荐,以及在什么情况下? “启动编码器”是什么意思?你是不是一次向作家写一个角色? (我们不太了解你如何使用作者......这可能很重要。)
BufferedOutputStream然后将缓冲来自Writer的字节,以避免一次将一个字节放到网络上。
是什么让你认为它会一次写一个字节?我认为OutputStreamWriter
不太可能一次写一个字节到底层编写器,除非你真的一次写一个字符。
此外,我希望网络输出流使用类似Nagle's algorithm的内容来避免发送单字节数据包。
与优化一样,你应该根据证据做到这一点......你有没有这些缓冲层进行任何测试?
编辑:只是为了澄清,我不是说缓冲类是没用的。在某些情况下,他们绝对是正确的方式。我只是说,与所有优化一样,不应盲目使用它们。您应该考虑要优化的内容(处理器使用情况,内存使用情况,网络使用情况等)和度量。这里有许多重要因素 - 其中最重要的是写模式。如果您已经“大块地”编写 - 编写大块字符数据 - 那么缓冲区的影响相对较小。如果你实际上是一次向作家写一个角色,那么它们会更重要。答案 2 :(得分:1)
是的,它有点矫枉过正。从Javadoc for OutputStreamWriter
开始:“write()方法的每次调用都会导致在给定字符上调用编码转换器。结果字节在写入底层输出流之前会累积在缓冲区中。”