我需要测量上传和下载大文件的中间吞吐量(使用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()不同,WritableByteChannel
的write()方法返回实际写入的字节数。所以它必须是非阻塞的,对吧?没有这样的运气。此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后)和counter reset bugs on some platforms等场景,以便在3G和Wifi之间切换。
有人能给我一个出路吗?
答案 0 :(得分:0)
为什么只有write()块,而read()不是?
因为这是底层操作系统的行为方式。