【发布时间】:2012-04-28 01:56:51
【问题描述】:
我需要测量上传和下载大文件的中间吞吐量(通过 FTP 使用Apache Commons Net API)。
下载:(没问题)
一切都可以下载,使用如下代码:
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 bugson some platforms 在 3G 和 Wifi 之间切换等场景。
谁能告诉我一条出路?
【问题讨论】:
标签: java android nio apache-commons java-io