Я использую OkHttpClient для приложения 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: он работает для файлов меньшего размера, чем тот, который он не загружает.
Проблема в том, что вы выполняете запрос диапазона, запрашивая последний байт из 3746316 байтов, составляющих ответ.
В ответ вы получите код состояния 206 согласно RFC 7233:
The 206 (Partial Content) status code indicates that the server is successfully fulfilling a range request for the target resource by transferring one or more parts of the selected representation that correspond to the satisfiable ranges found in the request's Range header field (Section 3.1).
Причина, по которой вы получаете это исключение, заключается в следующем фрагменте кода:
if (response.code() != 200) {
throw new IOException(String.valueOf(response.code()));
}
Вместо этого вы должны проверить, является ли ответ успешным (т.е. имеет ли он статус 2xx), что можно сделать следующим образом:
if (!response.isSuccessful()) {
throw new IOException(...);
}
Однако обратите внимание, что ваш код успешно создаст RandomAccessFile с содержимым ответа, то есть в этом случае одним байтом, что, вероятно, не предназначено.