1

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

下载:(没问题)

一切都很好下载,它使用如下代码:

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() 才阻塞。这使我能够测量中间下载吞吐量。到目前为止,一切都很好。

上传:(有问题)

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

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

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

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);

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

一种方法是使用 Android 的TrafficStatsAPI。但它也有自己的挫败感。根据文档,这些统计信息可能并非在所有平台上都可用。此外,它还需要处理整数计数器溢出(2GB 之后)等场景,以及在 3G 和 Wifi 之间切换时某些平台上的计数器重置错误。

有人可以告诉我一条出路吗?

4

1 回答 1

0

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

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

于 2012-04-19T22:01:25.263 回答