Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/368.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java=下载缓冲区未完全填满?冲洗/缓冲是如何工作的?_Java_Stream_Io_Buffer - Fatal编程技术网

Java=下载缓冲区未完全填满?冲洗/缓冲是如何工作的?

Java=下载缓冲区未完全填满?冲洗/缓冲是如何工作的?,java,stream,io,buffer,Java,Stream,Io,Buffer,我想监控下载数据的进度。我想在传输了一定数量的数据后进行日志记录。我的代码: int contentLength = 0; final int bufferSize = 1024*8; byte[] buffer = new byte[bufferSize]; int length = 0; while ( (length = bufferedInputStream.read(buffer) ) !=-1 ) { contentLength = contentLength+length

我想监控下载数据的进度。我想在传输了一定数量的数据后进行日志记录。我的代码:

int contentLength = 0;
final int bufferSize = 1024*8;
byte[] buffer = new byte[bufferSize];
int length = 0;

while ( (length = bufferedInputStream.read(buffer) ) !=-1 ) {
    contentLength = contentLength+length;

    if ( (contentLength % (bufferSize*1024*4)) ==0 ) {
                logger.debug(contentLength);
    }   
}
这似乎不起作用。似乎缓冲区并不总是满的,因此用作模的缓冲区大小的倍数不匹配

缓冲区不“满”真的很常见吗?这怎么会发生?bufer被“刷新”的内在逻辑是什么?Java是否等待s的特定时间来接收数据包,然后刷新(如果缓冲区未满)?任何关于它内部工作原理的信息都有助于理解它

(我不需要解决方案,我已经在其他地方实现了它,只是想知道缓冲区从未被完全读取是否很常见?我想知道为什么。)

非常感谢!
延斯

不能保证缓冲区已满。这些是IO的细节。必须使用
read
的返回值来确定实际读取了多少数据。

不能保证缓冲区已满。这些是IO的细节。您必须使用
read
的返回值来确定实际读取了多少数据。

当您可以
读取(字节[,…)
API时,流将尝试填充缓冲区中分配的空间。但它并不总能填满它。当然,如果流中的内容用完了,它就无法填满整个空间。但也有其他原因。例如,流实现可以使用一些后台线程来获取数据。如果read调用被传递到操作系统,那么它一次可以读取一个数据块。如果流已缓冲,并且缓冲区仍有一些内容,则它可能只返回缓冲区中剩余的内容。

当您可以读取(字节[…])API时,流将尝试填充缓冲区中分配的空间。但它并不总能填满它。当然,如果流中的内容用完了,它就无法填满整个空间。但也有其他原因。例如,流实现可以使用一些后台线程来获取数据。如果read调用被传递到操作系统,那么它一次可以读取一个数据块。如果流已缓冲,而缓冲区仍有一些内容,则它可能只返回缓冲区中剩余的内容。

套接字上的读取操作通常不会完全填充缓冲区。发送方正在刷新不同长度的数据包。然后,它们通过应用程序层、操作系统层和网络层,这些应用程序层、操作系统层和网络层可能会将它们分割开来。典型的结果是部分缓冲区读取

我通常会调整读取缓冲区的大小以匹配作为最大大小的缓冲区,但我从不依赖于每次都将其填满


另外,您应该注意,在执行大容量读取(到字节数组中)时,使用
BufferedInputStream
效率很低。这只会增加从一个数组到另一个数组复制数据的开销。这也是上面提到的碎片的来源之一。

套接字上的读取操作无法准确填充缓冲区是很常见的。发送方正在刷新不同长度的数据包。然后,它们通过应用程序层、操作系统层和网络层,这些应用程序层、操作系统层和网络层可能会将它们分割开来。典型的结果是部分缓冲区读取

我通常会调整读取缓冲区的大小以匹配作为最大大小的缓冲区,但我从不依赖于每次都将其填满


另外,您应该注意,在执行大容量读取(到字节数组中)时,使用
BufferedInputStream
效率很低。这只会增加从一个数组到另一个数组复制数据的开销。它也是上述碎片的来源之一。

这实际上取决于您使用的实际
InputStream
,归结为“操作系统如何处理
read()
调用”

在大多数现代操作系统上,basic
read
调用的作用是相同的:它尝试读取所请求的数据,但可能会提前停止

当缓冲区大于文件系统的预读缓冲区时,很容易发生这种情况。或者,当您从网络连接读取数据时,只有几个数据包到达

有些设备具有很好的预测性能(从文件系统读取的数据往往会完全填满提供的缓冲区(如果缓冲区不太大的话),从网络读取的数据往往会让缓冲区填满一半)。但你不能以这种或那种方式依赖它


因此:是的,这很容易发生。

这实际上取决于您使用的实际
InputStream
,归结为“操作系统如何处理
read()
调用”

在大多数现代操作系统上,basic
read
调用的作用是相同的:它尝试读取所请求的数据,但可能会提前停止

当缓冲区大于文件系统的预读缓冲区时,很容易发生这种情况。或者,当您从网络连接读取数据时,只有几个数据包到达

有些设备具有很好的预测性能(从文件系统读取的数据往往会完全填满提供的缓冲区(如果缓冲区不太大的话),从网络读取的数据往往会让缓冲区填满一半)。但你不能以这种或那种方式依赖它

所以:是的,这很容易发生