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() ブロックしません。これにより、中間のダウンロード スループットを測定できます。ここまでは順調ですね。

アップロード: (問題あり)

今、痛みが来ます。に書き込むために同様のサイズのバッファを割り当てると、256 KB 全体が書き込まれるまでOutputStream呼び出しがブロックされます。write()

write()ブロックしないのに、ブロックするだけなのはなぜread()ですか?

ということで使ってみましたnio。の write()とは異なりOutputstream、 の 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);

では、アップロードがブロックされているときに中間スループットを測定するにはどうすればよいでしょうか?

1 つの方法は、Android のTrafficStatsAPIを使用することです。しかし、それには独自の一連のフラストレーションが伴います。ドキュメントによると、これらの統計はすべてのプラットフォームで利用できるわけではありません。また、整数カウンター オーバーフロー (2GB 以降) や、3G と Wifi を切り替える際の一部のプラットフォームでのカウンター リセット バグ などのシナリオの処理も必要です。

誰かが抜け道を教えてくれますか?

4

1 に答える 1