我正在使用HTTP Range请求部分下载文件并将它们合并在一起。这适用于HTTP,但使用HTTPS时,inputStream读取的字节数非常少,需要很长时间才能完成。
此外,我不想删除Tread.Sleep(100)
因为CPU使用率上升到100%。
当前源代码:
@Override
public Boolean call() throws Exception
{
//Preparing Connection and setting ranges.
HttpURLConnection urlConnection =
(HttpURLConnection) fileLocation.openConnection();
urlConnection.setRequestProperty(
"Range", "Bytes=" + chunkStart + "-" + chunkEnd);
InputStream inputStream = urlConnection.getInputStream();
if (urlConnection.getResponseCode() != HttpURLConnection.HTTP_PARTIAL)
{
throw new Exception("Server returned status Code: " +
urlConnection.getResponseCode());
}
ByteBuffer buffer = ByteBuffer.allocate((int)(chunkEnd - chunkStart));
long bytesRead = 0;
// Copying the inputStream to my byteBuffer
ReadableByteChannel inputChannel = Channels.newChannel(inputStream);
while ((bytesRead = inputChannel.read(buffer)) > 0)
{
System.out.println("Bytes read: " + bytesRead);
Thread.sleep(100);
}
long writeOffset = chunkStart;
buffer.flip();
while (buffer.hasRemaining())
{
writeOffset += file.write(buffer, writeOffset);
}
buffer.clear();
return true;
}
下载10mb文件。 使用HTTP输出:(大约需要2秒)
Bytes read: 197102
Bytes read: 365844
Bytes read: 218372
Bytes read: 253512
Bytes read: 336256
...
使用HTTPS输出:(大约需要5分钟)
Bytes read: 320
Bytes read: 1389
Bytes read: 1389
Bytes read: 1389
Bytes read: 1389
Bytes read: 1389
...
删除Thread.sleep
会使用HTTPS提供此输出:(大约需要2秒,但CPU使用率约为99%)
Bytes Read: 1389
Bytes Read: 1389
Bytes Read: 1389
Bytes Read: 1389
Bytes Read: 1389
...
Bytes Read: 16384
Bytes Read: 16384
Bytes Read: 16384
Bytes Read: 16384
我还尝试将inputStream手动读取到byteArray,然后将其写入byteBuffer或使用BufferedInputStream,但我得到相同的结果。
我在这个主题上发现了一个非常相似的案例,但我不确定是否这样 真的是正确的解决方案Java ssl performance issue in connection with downloads
更新:我查看了System.setProperty("javax.net.debug","ssl:packet")
的SSLSocket调试信息,这就是我得到的
TLSv1.2 : TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
BufferSize: 16916
Packet Buffer Size: 16921
[Raw read]: length = 1413
0000: 00 00 00 00 00 00 00 01 CD 87 B9 AD B3 60 94 93 .............`..
0010: D5 13 0E 5A 3F D0 5D CE C1 46 93 62 23 67 77 57 ...Z?.]..F.b#gwW
0020: 39 D4 07 46 96 89 72 12 2F 91 74 92 D8 C4 8F A4 9..F..r./.t.....
...more and more
0570: 04 E1 83 F6 7E 72 8A 38 5F EA 2B A0 F5 75 C3 57 .....r.8_.+..u.W
0580: 78 23 5E 01 AB x#^..
pool-1-thread-1, READ: TLSv1.2 Application Data, length = 1413
Padded plaintext after DECRYPTION: len = 1389
这就解释了为什么我每次调用只能读取1389个字节,但是如果所有缓冲区大小都大得多,并且如果我在没有Thread.sleep
的情况下运行它,它将如何增加这个大小。它几乎被填满。