Резюме загрузки http файлов в java
URL url = new URL("http://download.thinkbroadband.com/20MB.zip");
URLConnection connection = url.openConnection();
File fileThatExists = new File(path);
OutputStream output = new FileOutputStream(path, true);
connection.setRequestProperty("Range", "bytes=" + fileThatExists.length() + "-");
connection.connect();
int lenghtOfFile = connection.getContentLength();
InputStream input = new BufferedInputStream(url.openStream());
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
output.write(data, 0 , count);
}
в этом коде я пытаюсь возобновить загрузку. Целевой файл - 20 МБ. Но когда я прекращаю загрузку на 10mb, тогда contunue, я получаю файл с размером файла 30 МБ. Кажется, что он продолжает писать в файл, но частично не может загружаться с сервера. Wget -c отлично работает с этим файлом. Как возобновить загрузку файла?
Ответы
Ответ 1
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
if(ISSUE_DOWNLOAD_STATUS.intValue()==ECMConstant.ECM_DOWNLOADING){
File file=new File(DESTINATION_PATH);
if(file.exists()){
downloaded = (int) file.length();
connection.setRequestProperty("Range", "bytes="+(file.length())+"-");
}
}else{
connection.setRequestProperty("Range", "bytes=" + downloaded + "-");
}
connection.setDoInput(true);
connection.setDoOutput(true);
progressBar.setMax(connection.getContentLength());
in = new BufferedInputStream(connection.getInputStream());
fos=(downloaded==0)? new FileOutputStream(DESTINATION_PATH): new FileOutputStream(DESTINATION_PATH,true);
bout = new BufferedOutputStream(fos, 1024);
byte[] data = new byte[1024];
int x = 0;
while ((x = in.read(data, 0, 1024)) >= 0) {
bout.write(data, 0, x);
downloaded += x;
progressBar.setProgress(downloaded);
}
Это не мой код, но он работает.
Ответ 2
Я думаю, проблема, с которой вы столкнулись, вызывает url.openStream()
после url.openConnection()
.
url.openStream()
эквивалентен url.openConnection().getInputStream()
. Следовательно, вы запрашиваете URL-адрес дважды. В частности, во второй раз это не указывает свойство диапазона. Поэтому загрузка всегда начинается с начала.
Вы должны заменить url.openStream()
на connection.getInputStream()
.
Ответ 3
Отметьте этот поток, который имеет проблему, похожую на вашу. Если wget работает, сервер явно поддерживает возобновление загрузки. Похоже, вы не устанавливаете заголовок If-Range
, как указано в принятом ответе вышеуказанной ссылки. то есть. добавить:
// Initial download.
String lastModified = connection.getHeaderField("Last-Modified");
// ...
// Resume download.
connection.setRequestProperty("If-Range", lastModified);
Ответ 4
Поскольку вопрос отмечен Android:
Вы пробовали использовать DownloadManager.
Он отлично справляется со всем этим.
Ответ 5
У меня есть способ работать с вашим кодом.
- Сначала проверьте, завершен ли файл или нет.
-
Если файл существует, установите соединение:
connection.setRequestProperty("Range", "bytes=" + bytedownloaded + "-");
-
Если файл не существует, выполните ту же загрузку в новом файле.
Ответ 6
Как насчет этого?
public static void download(DownloadObject object) throws IOException{
String downloadUrl = object.getDownloadUrl();
String downloadPath = object.getDownloadPath();
long downloadedLength = 0;
File file = new File(downloadPath);
URL url = new URL(downloadUrl);
BufferedInputStream inputStream = null;
BufferedOutputStream outputStream = null;
URLConnection connection = url.openConnection();
if(file.exists()){
downloadedLength = file.length();
connection.setRequestProperty("Range", "bytes=" + downloadedLength + "-");
outputStream = new BufferedOutputStream(new FileOutputStream(file, true));
}else{
outputStream = new BufferedOutputStream(new FileOutputStream(file));
}
connection.connect();
inputStream = new BufferedInputStream(connection.getInputStream());
byte[] buffer = new byte[1024*8];
int byteCount;
while ((byteCount = inputStream.read(buffer)) != -1){
outputStream.write(buffer, 0, byteCount);
break;
}
inputStream.close();
outputStream.flush();
outputStream.close();
}
Используется break;
для проверки кода..;)