在写入 OutputStream 时测量中间吞吐量 [或] 为什么 write() 阻塞,而 read() 不是? [英] Measure intermediate throughput when writing to OutputStream [or] Why is write() blocking, while read() is not?

查看:31
本文介绍了在写入 OutputStream 时测量中间吞吐量 [或] 为什么 write() 阻塞,而 read() 不是?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要测量上传和下载大文件的中间吞吐量(通过 FTP 使用 Apache Commons Net API).

I need to measure the intermediate throughput of uploading and downloading a large file (via FTP using Apache Commons Net API).

下载:(没问题)

下载一切正常,使用如下代码:

Everything is fine for downloading, which uses code like the following:

InputStream is = ftp.retrieveFileStream(filePath);
byte[] buffer = new byte[256 * 1024];
int read;

while ((read = is.read(buffer, 0, buffer.length)) != -1) {
    Log.v(TAG, "Read = " + read);
}

这里,缓冲区大小为 256 KB,下载的文件总大小为 1 MB.对 is.read() 的每个单独调用仍然只返回大约 2 KB.在这种情况下,read() 不会阻塞,直到缓冲区已满.这使我能够测量中间下载吞吐量.到目前为止一切顺利.

Here, the buffer is 256 KB in size, and the total size of the file being downloaded is 1 MB. Still each individual call to is.read() returns only about 2 KB. In this case read() does not block until the buffer is full. This enables me to measure intermediate download throughput. So far so good.

上传:(有问题)

痛苦来了.当我分配一个类似大小的缓冲区来写入 OutputStream 时,对 write() 的调用会阻塞,直到写入整个 256 KB.

Now comes the pain. When I allocate a similar sized buffer to write to an OutputStream, the call to write() blocks until the entire 256 KB is written.

为什么只有 write() 会阻塞,而 read() 不会?

Why does only write() block, whereas read() doesn't?

所以我尝试使用 nio.与Outputstream 的write() 不同,WritableByteChannel 的write() 方法返回实际写入的字节数.所以它必须是非阻塞的,对吧?没有这样的运气.这个 write() 也会阻塞,直到整个缓冲区被写入.代码如下:

So I tried to use nio. Unlike Outputstream's write(), the write() method of WritableByteChannel returns the number of bytes actually written. So it must be non-blocking, right? No such luck. This write() also blocks until the whole buffer is written. Here is the code:

byte[] buffer = new byte[256 * 1024];
new Random.nextBytes(byteArray);

OutputStream os = ftp.storeFileStream(filePath);
WritableByteChannel channel = Channels.newChannel(os);
ByteBuffer byteBuffer = ByteBuffer.wrap(byteArray);
int written = channel.write(byteBuffer);

那么,当上传被阻塞时,我如何测量中间吞吐量?

So how can I measure the intermediate throughput when the upload is blocking?

一种方法是使用 Android 的 TrafficStats API.但它也带来了一系列的挫折.根据文档,这些统计数据可能并非在所有平台上都可用.它还需要处理整数计数器溢出(2GB 之后)和计数器重置错误在某些平台上,在 3G 和 Wifi 之间切换时.

One way is to use Android's TrafficStats API. But it comes with its own set of frustrations. As per the documentation, these statistics may not be available on all platforms. Also it needs handling of scenarios like integer counter overflow (after 2GB), and counter reset bugs on some platforms when switching between 3G and Wifi.

有人能给我指路吗?

推荐答案

为什么只有 write() 会阻塞,而 read() 不会?

Why does only write() block, whereas read() doesn't?

因为这是底层操作系统的行为方式.

Because that's the way the underlying operating system behaves.

这篇关于在写入 OutputStream 时测量中间吞吐量 [或] 为什么 write() 阻塞,而 read() 不是?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆