有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java在写入OutputStream时测量中间吞吐量[或者]为什么write()阻塞,而read()不阻塞?

我需要测量上传和下载大文件的中间吞吐量(通过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);
}

这里,缓冲区的大小是256KB,下载文件的总大小是1MB。但是,对is.read()的每个单独调用只返回大约2kb。在这种情况下read()在缓冲区满之前不会阻塞。这使我能够测量中间下载吞吐量。到目前为止还不错

上传:(有问题)

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

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

所以我试着用^{}。与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的^{} API。但它也有自己的挫折。根据文件,这些统计数据可能并非在所有平台上都可用。它还需要处理诸如整数计数器溢出(2GB之后)和在3G和Wifi之间切换时counter reset bugs{a5}等情况

有人能告诉我一条出路吗


共 (1) 个答案

  1. # 1 楼答案

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

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