我需要测量上传和下载大文件的中间吞吐量(通过使用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 的TrafficStats
API。但它也有自己的挫败感。根据文档,这些统计信息可能并非在所有平台上都可用。此外,它还需要处理整数计数器溢出(2GB 之后)等场景,以及在 3G 和 Wifi 之间切换时某些平台上的计数器重置错误。
有人可以告诉我一条出路吗?