J'essaie d'implémenter une pause/reprise dans mon gestionnaire de téléchargement, je fais des recherches sur le Web, je lis plusieurs articles et je modifie mon code en fonction de ceux-ci, mais CV semble ne pas fonctionner correctement. Des idées?
if (!downloadPath.exists())
downloadPath.mkdirs();
if (outputFileCache.exists())
{
downloadedSize = outputFileCache.length();
connection.setAllowUserInteraction(true);
connection.setRequestProperty("Range", "bytes=" + downloadedSize + "-");
connection.setConnectTimeout(14000);
connection.connect();
input = new BufferedInputStream(connection.getInputStream());
output = new FileOutputStream(outputFileCache, true);
input.skip(downloadedSize); //Skip downloaded size
}
else
{
connection.setConnectTimeout(14000);
connection.connect();
input = new BufferedInputStream(url.openStream());
output = new FileOutputStream(outputFileCache);
}
fileLength = connection.getContentLength();
byte data[] = new byte[1024];
int count = 0;
int __progress = 0;
long total = downloadedSize;
while ((count = input.read(data)) != -1 && !this.isInterrupted())
{
total += count;
output.write(data, 0, count);
__progress = (int) (total * 100 / fileLength);
}
output.flush();
output.close();
input.close();
Ok problème résolu, voici mon code pour les autres utilisateurs qui veulent implémenter pause/resume
if (outputFileCache.exists())
{
connection.setAllowUserInteraction(true);
connection.setRequestProperty("Range", "bytes=" + outputFileCache.length() + "-");
}
connection.setConnectTimeout(14000);
connection.setReadTimeout(20000);
connection.connect();
if (connection.getResponseCode() / 100 != 2)
throw new Exception("Invalid response code!");
else
{
String connectionField = connection.getHeaderField("content-range");
if (connectionField != null)
{
String[] connectionRanges = connectionField.substring("bytes=".length()).split("-");
downloadedSize = Long.valueOf(connectionRanges[0]);
}
if (connectionField == null && outputFileCache.exists())
outputFileCache.delete();
fileLength = connection.getContentLength() + downloadedSize;
input = new BufferedInputStream(connection.getInputStream());
output = new RandomAccessFile(outputFileCache, "rw");
output.seek(downloadedSize);
byte data[] = new byte[1024];
int count = 0;
int __progress = 0;
while ((count = input.read(data, 0, 1024)) != -1
&& __progress != 100)
{
downloadedSize += count;
output.write(data, 0, count);
__progress = (int) ((downloadedSize * 100) / fileLength);
}
output.close();
input.close();
}
Il est impossible de dire ce qui ne va pas sans quelques informations supplémentaires, mais notez les points suivants:
Vous devriez vérifier votre demande d'intervalle avec quelque chose de simple pour tester l'origine car elle prend en charge d'abord la demande d'intervalle (comme curl ou wget)
Il se peut que votre serveur prenne trop de temps à répondre (plus que le délai imparti) ou il est également indéniable que tous les serveurs ne prennent pas en charge la pause - resume . via Http, https, ftp ou udp.
Pause "peut signifier simplement lire une partie du flux et l’écrire sur le disque. Lors de la reprise, vous devrez utiliser les en-têtes pour spécifier le contenu restant à télécharger .
vous pouvez essayer quelque chose comme:
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);
}
et s'il vous plaît essayez de synchroniser les choses.
Je commencerais le débogage à partir de cette ligne:
connection.setRequestProperty("Range", "bytes=" + downloadedSize + "-");
À partir du code source, il n'est pas possible de déterminer ce que downloadedSize
est, il est difficile d'élaborer plus avant, mais le format devrait être bytes=from-to
.
Quoi qu'il en soit, je vous suggère d'utiliser Apache HttpClient pour éviter les pièges courants. Ici est une question de quelqu'un qui utilise Apache HttpClient sur un sujet similaire et qui fournit un exemple de code.
Je pense que vous avez juste besoin de supprimer la ligne input.skip (downloadsSize). Définir l'en-tête HTTP pour la plage d'octets signifie que serveur ignorera envoyant ces octets.
Supposons que vous ayez un fichier de 20 octets comprenant "aaaaabbbbbccccddddd", et supposons que le transfert soit mis en pause après le téléchargement de 5 octets. Ensuite, l'en-tête Range fera en sorte que le serveur envoie "bbbbbcccccddddd". Vous devez lire all de ce contenu et l'ajouter au fichier - no skip (). Mais l'appel skip () dans votre code ignorera "bbbbb", laissant "cccccddddd" à télécharger. Si vous avez déjà téléchargé au moins 50% du fichier, alors skip () épuisera toutes les entrées et rien ne se passera.
En outre, toutes les choses dans le post de stringy05 s'appliquent. Vous devez vous assurer que le serveur prend en charge HTTP/1.1, que l'en-tête Range est pris en charge pour la ressource (le contenu généré de manière dynamique peut ne pas le prendre en charge) et que la ressource n'est pas modifiée à l'aide de etag et de la date de modification.