我正在使用OkHttpClient for android应用程序从服务器下载PDF文件,下载PDF文件时出现异常。
System.err: java.io.IOException: 206
这是响应元素:
Date: Tue, 27 Nov 2018 12:45:17 GMT
Server: Apache/2.4.23 (Win64) PHP/5.6.25
Last-Modified: Mon, 09 Jan 2017 16:06:27 GMT
ETag: "392a0c-545ab8ccd2dc8"
Accept-Ranges: bytes
Content-Length: 1
Content-Range: bytes 3746315-3746315/3746316
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: application/pdf
OkHttp-Sent-Millis: 1543322716318
OkHttp-Received-Millis: 1543322716467
这是用来下载文件的代码:
private final static int BUFFER_SIZE = 1024 * 8;
Request.Builder requestBuilder = new Request.Builder().url(itemUrl);
try {
Response response =
getOkHttpClient().newCall(requestBuilder.build()).execute();
long totalSize = response.body().contentLength();
if (response.code() != 200) {
throw new IOException(String.valueOf(response.code()));
}
RandomAccessFile out = new RandomAccessFile(tempItemFilePath, "rw");
byte[] buffer = new byte[BUFFER_SIZE];
BufferedInputStream in = new BufferedInputStream(response.body().byteStream(), BUFFER_SIZE);
long bytesCount = 0;
int bytesRead = 0;
try {
out.seek(out.length());
while (true) {
bytesRead = in.read(buffer, 0, BUFFER_SIZE);
if (bytesRead == -1) {
break;
}
out.write(buffer, 0, bytesRead);
manager.setDownloadStatus(magazine, ((bytesCount * 100) / totalSize));
bytesCount += bytesRead;
EventBus.getDefault().post(new DownloadStatusUpdateEvent());
}
} finally {
out.close();
if (in != null) {
in.close();
}
in.close();
}
}
知道为什么它不起作用吗? PS:它适用于小于未下载文件的文件。
答案 0 :(得分:0)
问题是您正在range request中请求构成响应的3746316字节中的最后一个字节。
作为回应,您将获得206状态码,根据RFC 7233:
206(部分内容)状态代码表示服务器处于 通过以下方式成功满足目标资源的范围请求 转移所选表示形式的一个或多个部分 对应于请求范围内的可满足范围 标头字段(第3.1节)。
出现该异常的原因是这段代码:
if (response.code() != 200) {
throw new IOException(String.valueOf(response.code()));
}
您应该检查的是响应是否成功(即状态是否为2xx),可以通过以下方式完成:
if (!response.isSuccessful()) {
throw new IOException(...);
}
请注意,尽管您的代码将成功创建一个包含响应内容的RandomAccessFile
,即在这种情况下为单个字节,这可能不是故意的。