Java-使用带套接字的DataInputStream,是否缓冲?
我正在编写一个简单的客户机/服务器应用程序,我发现使用DataInputStream读取数据非常方便,因为它允许您选择要读取的内容(无需自己将其从字节转换),但我想知道是否最好也将其封装在BufferedInputStream中,或者这只会增加不必要的开销 我问这个问题的原因是因为我不知道直接从套接字流读取有多昂贵(当使用BufferedInputStream时,它只会从套接字流读取一次,然后使用DataInputStream从BufferedInputStream读取倍数) 接收到的数据通常很小,大约20-25字节Java-使用带套接字的DataInputStream,是否缓冲?,java,sockets,tcp,bufferedinputstream,Java,Sockets,Tcp,Bufferedinputstream,我正在编写一个简单的客户机/服务器应用程序,我发现使用DataInputStream读取数据非常方便,因为它允许您选择要读取的内容(无需自己将其从字节转换),但我想知道是否最好也将其封装在BufferedInputStream中,或者这只会增加不必要的开销 我问这个问题的原因是因为我不知道直接从套接字流读取有多昂贵(当使用BufferedInputStream时,它只会从套接字流读取一次,然后使用DataInputStream从BufferedInputStream读取倍数) 接收到的数据通常很
提前感谢您的回答!:DDataInputStream没有缓冲,因此
DataInputStream
对象上的每个读取操作都将导致底层套接字流上的一个或多个读取,这可能会导致多个系统调用(或等效调用)
系统调用通常比常规方法调用要贵2到3个数量级。缓冲流的工作方式是减少系统调用的数量(理想情况下为1),但代价是增加一层额外的常规方法调用。通常,使用缓冲流将N个系统调用替换为1个系统调用和N个额外的方法调用。如果N大于1,则您获胜
因此,在套接字流和DataInputStream之间放置BufferedInputStream不是win的唯一情况是:
- 当应用程序只进行一次
调用,并且一次系统调用即可满足该调用时read…()
- 当应用程序仅执行大型
调用时,或读取(字节[…)
- 当应用程序不读取任何内容时
最后一点,实际读取的数据量(即消息的大小)与缓冲与非缓冲的难题几乎无关。真正重要的是数据的读取方式;i、 e.应用程序将进行的
read…()
调用的顺序。一般认为,底层流上的单个读取非常慢,因此缓冲几乎总是更快。然而,对于这样小的数字(20-25字节),分配缓冲器的成本可能与制造这些单独读取的成本相似(一旦考虑内存分配和垃圾收集)。不幸的是,找到答案的唯一方法是测试它并查看
您说接收到的数据通常很小:您希望多长时间收到更大的消息?如果您在未缓冲的流中偶尔收到大消息,这将是一个重要的瓶颈
我建议您运行一些计时测试,看看缓冲是否会对您的情况产生影响。或者,不必费心计时测试,只需使用缓冲区即可。如果将来消息大小发生变化,则这将减少以后的维护。这没有意义。缓冲区在套接字的生命周期内分配一次。可以有任意数量的读取。读取越小,缓冲就越有意义。如果客户端正在连接,发送一条小消息,然后断开连接(就像Ajax-y可能做的那样),那么缓冲可能效率低下。读取的数量必须非常小,但20-25的范围可能足够小。我不知道:这就是我建议评测的原因。现在我想了想,AJAX不会得到20-25字节的消息……XML太冗长了。尽管如此,我还是认为客户不会保持他们的联系。如果这个假设是错误的,那么一定要使用缓冲区。我在他的帖子中没有看到任何东西可以证明你的假设是正确的。他特别提到多次读取,所以要么他一次读取一个字节,这将证明BufferedInputStream是正确的,要么他自己分配一个缓冲区,这正是您以另一种形式提到的开销。为了澄清问题,我保持连接打开,我不断地向它发送每个包含20-25个字节的新数据,然后用多个readInt()、readByte()等来读取它(现在我还在缓冲它)