2

这更像是良心问题而不是技术问题:p 我正在编写一些 java 代码来从服务器下载文件...为此,我使用的是 BufferedOutputStream 方法 write() 和 BufferedInputStream 方法 read() .

所以我的问题是,如果我使用缓冲区来保存字节,那么要读取的字节数应该是多少?当然,我可以使用 int byte = read() 然后 write(byte) 逐字节读取,或者我可以使用缓冲区。如果我采用第二种方法,在定义每次读取\写入的字节数时,是否有哪些方面我必须注意?这个数字对我的程序有什么影响?

谢谢

4

4 回答 4

1

除非你有一个非常快的网络连接,否则缓冲区的大小几乎没有什么区别。我会说 4k 缓冲区会很好,尽管使用更大一点的缓冲区没有害处。

read()假设read(byte[])您使用的是BufferedInputStream.

除非您拥有非常快/低延迟的网络连接,否则瓶颈将是网络和计算机网络接口可以维持的数据速率。对于典型的 Internet 连接,应用程序移动数据的速度可以比网络快两个或更多数量级。因此,除非您做一些愚蠢的事情(例如在无缓冲流上读取 1 个字节),否则您的 Java 代码不会成为瓶颈。

于 2012-05-29T10:55:19.653 回答
1

BufferedInputStream 和 BufferedOutputStream 通常依赖 System.arraycopy 来实现。System.arraycopy 有一个本地实现,它可能依赖于 memmove 或 bcopy。复制的内存量将取决于缓冲区中的可用空间,但无论如何,到本机代码的实现非常有效,无论您正在读取/写入多少字节,都不太可能影响应用程序的性能。

但是,对于 BufferedInputStream,如果您设置了一个上限标记,则可能需要创建一个新的内部缓冲区。如果您确实使用了标记,则读取的字节数超过旧缓冲区中可用的字节数可能会导致暂时的性能下降,尽管摊销后的性能仍然是线性的。

正如 Stephen C 所提到的,由于网络,您更有可能看到性能问题。

于 2012-05-29T11:21:12.943 回答
0

您的网络连接中的 MTU(最大流量单位)是多少?例如,如果您使用 UDP,则可以检查此值并使用较小的字节数组。如果这是没有办法的,你需要检查内存是如何吃掉你的程序的。我认为1024 - 4096保存这些数据并继续接收将是一个很好的变体

于 2012-05-29T10:54:04.167 回答
0

如果您泵送数据,您通常不需要使用任何缓冲流。只需确保您使用传递给 read 方法的适当大小(8-64k)的临时 byte[] 缓冲区(或使用执行此操作的泵方法)。对于大多数用途而言,默认缓冲区大小太小(如果您使用更大的临时数组,它将被忽略)

于 2014-10-09T00:05:19.557 回答