Reprendre le téléchargement du fichier http en 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); } 

dans ce code, j’essaie de reprendre le téléchargement. Le fichier cible est de 20 Mo. Mais quand j’arrête le téléchargement sur 10 Mo, puis continue, je reçois un fichier avec une taille de fichier de 30 Mo. Il semble qu’il continue à écrire dans un fichier, mais ne peut pas télécharger partiellement depuis le serveur. Wget -c fonctionne très bien avec ce fichier. Comment puis-je reprendre le téléchargement du fichier?

  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); } 

Ce n’est pas mon code mais ça marche.

Je suppose que le problème auquel vous êtes confronté est d’appeler url.openStream() après url.openConnection() .

url.openStream() est équivalent à url.openConnection().getInputStream() . Par conséquent, vous demandez l’URL deux fois. En particulier la deuxième fois, il ne spécifie pas la propriété range. Par conséquent, le téléchargement commence toujours au début.

Vous devez remplacer url.openStream() par connection.getInputStream() .

Découvrez ce sujet qui a un problème similaire au vôtre . Si wget fonctionne, le serveur prend clairement en charge la reprise des téléchargements. Il semble que vous ne définissiez pas l’en If-Range tête If-Range comme indiqué dans la réponse acceptée du lien ci-dessus. c’est à dire. append:

 // Initial download. Ssortingng lastModified = connection.getHeaderField("Last-Modified"); // ... // Resume download. connection.setRequestProperty("If-Range", lastModified); 

Puisque la question est étiquetée avec Android: Avez-vous essayé d’utiliser DownloadManager . Il gère tout cela gentiment pour vous.

Que dis-tu de ça?

 public static void download(DownloadObject object) throws IOException{ Ssortingng downloadUrl = object.getDownloadUrl(); Ssortingng 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; utilisée pour tester le code ..;)

C’est ce que j’utilise pour télécharger le fichier en bloc. Mise à jour de l’interface utilisateur avec les progrès.

/ ** @param callback = Mettre à jour l’interface utilisateur avec l’action appropriée

  * @param fileName = Name of the file by which downlaoded file will be saved. * @param downloadURL = File downlaoding URL * @param filePath = Path where file will be saved * @param object = Any object you want in return after download is completed to do certain operations like insert in DB or show toast */ public void startDownload(final IDownloadCallback callback, Ssortingng fileName, Ssortingng downloadURL, Ssortingng filePath, Object object) { callback.onPreExecute(); // Callback to tell that the downloading is going to start int count = 0; File outputFile = null; // Path where file will be downloaded try { File file = new File(filePath); file.mkdirs(); long range = 0; outputFile = new File(file, fileName); /** * Check whether the file exists or not * If file doesn't exists then create the new file and range will be zero. * But if file exists then get the length of file which will be the starting range, * from where the file will be downloaded */ if (!outputFile.exists()) { outputFile.createNewFile(); range = 0; } else { range = outputFile.length(); } //Open the Connection URL url = new URL(downloadURL); URLConnection con = url.openConnection(); // Set the range parameter in header and give the range from where you want to start the downloading con.setRequestProperty("Range", "bytes=" + range + "-"); /** * The total length of file will be the total content length given by the server + range. * Example: Suppose you have a file whose size is 1MB and you had already downloaded 500KB of it. * Then you will pass in Header as "Range":"bytes=500000". * Now the con.getContentLength() will be 500KB and range will be 500KB. * So by adding the two you will get the total length of file which will be 1 MB */ final long lenghtOfFile = (int) con.getContentLength() + range; FileOutputStream fileOutputStream = new FileOutputStream(outputFile, true); InputStream inputStream = con.getInputStream(); byte[] buffer = new byte[1024]; long total = range; /** * Download the save the content into file */ while ((count = inputStream.read(buffer)) != -1) { total += count; int progress = (int) (total * 100 / lenghtOfFile); EntityDownloadProgress entityDownloadProgress = new EntityDownloadProgress(); entityDownloadProgress.setProgress(progress); entityDownloadProgress.setDownloadedSize(total); entityDownloadProgress.setFileSize(lenghtOfFile); callback.showProgress(entityDownloadProgress); fileOutputStream.write(buffer, 0, count); } //Close the outputstream fileOutputStream.close(); // Disconnect the Connection if (con instanceof HttpsURLConnection) { ((HttpsURLConnection) con).disconnect(); } else if (con instanceof HttpURLConnection) { ((HttpURLConnection) con).disconnect(); } inputStream.close(); /** * If file size is equal then return callback as success with downlaoded filepath and the object * else return failure */ if (lenghtOfFile == outputFile.length()) { callback.onSuccess(outputFile.getAbsolutePath(), object); } else { callback.onFailure(object); } } catch (Exception e) { e.printStackTrace(); callback.onFailure(object); } } 

interface IDownloadCallback {

  void onPreExecute(); // Callback to tell that the downloading is going to start void onFailure(Object o); // Failed to download file void onSuccess(Ssortingng path, Object o); // Downloaded file successfully with downloaded path void showProgress(EntityDownloadProgress entityDownloadProgress); // Show progress } 

classe publique EntityDownloadProgress {

  int progress; // range from 1-100 long fileSize;// Total size of file to be downlaoded long downloadedSize; // Size of the downlaoded file public void setProgress(int progress) {this.progress = progress;} public void setFileSize(long fileSize) {this.fileSize = fileSize;} public void setDownloadedSize(long downloadedSize) {this.downloadedSize = downloadedSize;} } 

J’ai un moyen de faire fonctionner votre code.

  1. Tout d’abord, vérifiez si le fichier se termine ou non
  2. Si le fichier existe, définissez la connexion:

     connection.setRequestProperty("Range", "bytes=" + bytedownloaded + "-"); 
  3. Si le fichier n’existe pas, faites le même téléchargement dans un nouveau fichier.