java - HTTP-Download - sometimes file is not downloaded complete without error -


i'm trying develope small java downloader. sometimes, can not find out when, 1 download missing few percent. after 1 download corrupt every download after corrupt. have no clue problem, , tried different output buffers no success. here source of download thread:

    private void startdownload() {         try {             ins = null;             outb=null;             setrunning(true);             // erstelle httpurlconnection objekt zur anfrage den server             con = (httpurlconnection)url.openconnection();             con.setrequestmethod("get");             con.setrequestproperty("user-agent", datacontroller.getinstance().getuseragentstring());             if (datacontroller.getinstance().getcookie() != null) {                 con.setrequestproperty("cookie", datacontroller.getinstance().getcookie());             }              system.out.println("saveto length: " + this.saveto );             system.out.println("loaded bytes : " + loadedbytes );              if (loadedbytes > 0) {                 // ist zieldatei noch vorhanden und stimmt die größe?                 if (saveto != null && saveto.exists() && saveto.length() == loadedbytes) {   // save null!!!                     // wiederaufnahme-position übermitteln                     con.setrequestproperty("range", "bytes=" + loadedbytes + "-");                 }                 else if (!saveto.exists()) {                     // zieldatei existiert nicht (mehr)                     try {                         if (!saveto.createnewfile()) {                             // zieldatei konnte nicht angelegt werden                              // saveto-objekt zurücksetzen und somit save-dialog provozieren                             saveto = null;                         }                     } catch (exception e) {                         // beim anlegen des files ist ein unerwarteter fehler aufgetreten                         e.printstacktrace();                          // saveto-objekt zurücksetzen und somit save-dialog provozieren                         saveto = null;                     }                  }             }             con.connect();              // prüfe response-code             rc = con.getresponsecode();              if (datacontroller.getinstance().isdebugmode()) system.out.println("rc " + rc);              if (rc == httpurlconnection.http_ok || rc == httpurlconnection.http_partial) {                  // wenn keine 206 partial content kam, loaded-zähler zurücksetzen, download von vorne beginnen                 if (rc == httpurlconnection.http_ok) {                     loadedbytes = 0;                 }                  string filename = getfilename();                  if (loadedbytes == 0) {                     size = long.valueof(con.getheaderfield("content-length")).longvalue();                 } else {                     size = loadedbytes + long.valueof(con.getheaderfield("content-length")).longvalue();                 }                  // fortschritts-event alle abonnenten senden                 (downloadprogresslistener l: progresslisteners) {                     l.setminimum(0);                     l.setmaximum(size);                     l.setvalue(loadedbytes);                     l.setfilename(filename);                     l.setstatus(downloadprogresslistener.status_running);                 }                  // autosave - wenn defaultsavepath gesetzt, baue dateipfad zusammen                 if (saveto == null && datacontroller.getinstance().getsettingscontroller().getdefaultsavepath() != null                      && datacontroller.getinstance().getsettingscontroller().getusedefaultsavepath()) {                       file savetmp = new file(datacontroller.getinstance().getsettingscontroller().getdefaultsavepath(), filename);                       // prüfe auf gültigkeit, wenn gültig - übernehmen                      if (savetmp.exists() || savetmp.createnewfile()) {                          saveto = savetmp;                           // filename-event auslösen, damit server den "neuen" zielpfad mitgeteilt bekommt                          (downloadprogresslistener l: progresslisteners) {                              l.setfilename(saveto.getname());                          }                      }                 }                  // wurde der speicherort (immer)noch nicht festgelegt?                 if (saveto == null) {                      // speichern-unter dialog öffnen                     filedialog dia = new filedialog(viewcontroller.getframe(), "save as", filedialog.save);                     dia.setfile(filename);                     dia.setvisible(true);                      //system.out.println("now: " + new date().gettime());                      if (dia.getfile() == null) {                         // user hat abbrechen gedrückt - download abbrechen und aus der liste entfernen                         if (datacontroller.getinstance().isdebugmode())                              system.out.println("download cancelled");                          datacontroller.getinstance().removedownload(url);                         return;                     }                      // settings-panel bescheidsagen, dass ein pfad ausgewählt wurde -> defaultsavepath-haken anzeigen                     datacontroller.getinstance().getsettingscontroller().setlastsavepath(new file(dia.getdirectory()));                      saveto = new file(dia.getdirectory(), dia.getfile());                      if (datacontroller.getinstance().isdebugmode())                         system.out.println("saving " + saveto.getabsolutepath());                       // neuen dateinamen event-abonnenten propagieren                     (downloadprogresslistener l: progresslisteners) {                         l.setfilename(saveto.getname());                     }                  }                 // erstelle einen neuen thread, der nun unabhängig von der oberfläche im hintergrund den download abarbeitet                 downloadthread = new thread(new runnable() {                      @override                     public void run() {                             try {                                 // netzwerk-stream öffnen                                 //ins = con.getinputstream();                                 // dateiausgabe-stream öffnen, rc == httpurlconnection.http_partial => append                                 // outb = new bufferedoutputstream(new fileoutputstream(saveto, rc == httpurlconnection.http_partial));                                 outb = new fileoutputstream(saveto, rc == httpurlconnection.http_partial);                                 bos = new bufferedoutputstream(outb);                                 bis = new bufferedinputstream(con.getinputstream());                                 loadedbytes = saveto.length();                                 byte data [] = new byte[1024];                                 int count;                                 long bytesread = 0;                                 long lasttime = system.currenttimemillis();                                 long = 0;                                 int bytespersecond = 0;                                 long timediff = 0;                                 int timeleft = 0;                                 system.out.println("first size loadedbytes "+loadedbytes);                                 // lese-schleife                                 //for (count = ins.read(data,0,1024); count >= 0; count = ins.read(data,0,1024))                                 while (( count = bis.read(data,0,1024)) > -1 )                                 {                                     // wenn download pausiert oder abgebrochen -> schleife abbrechen                                      if (stop || paused) break;                                      // daten schreiben, zähler erhöhen                                     bos.write(data,0,count);                                     bytesread += count;                                     loadedbytes += count;                                     = system.currenttimemillis();                                     timediff = system.currenttimemillis() - lasttime;                                     // mehr als 1 sekunde vergangen                                     if (timediff > 1000l) {                                          // geschwindigkeit und restzeit berechnen                                         bytespersecond = (int)math.round(((double)bytesread / (timediff)) * 1000.0);                                         bytesread = 0;                                         lasttime = now;                                         timeleft = (int)math.round((double)(size - loadedbytes) / bytespersecond);                                          // fortschritts-events auslösen                                         (downloadprogresslistener l: progresslisteners) {                                             l.setvalue(loadedbytes);                                             l.setspeed(bytespersecond);                                             l.settimeestimated(timeleft);                                         }                                         viewcontroller.refreshmainprogress();                                     }                                 }                                 //date timer = new date();                                 // ausgabe- und netzwerk-stream beenden                                 system.out.println("geladen: " + loadedbytes);                                 bos.flush();                                 bos.close();                                 bis.close();                                 outb.flush();                                 outb.close();                                 ins.close();                                 (downloadprogresslistener l: progresslisteners)                                  {                                     l.setstatus(downloadprogresslistener.status_checksum_verify);                                 }                                 viewcontroller.refreshmainprogress();                                  if (!paused) {                                          // wurde abgebrochen?                                         if (stop) {                                              // zieldatei löschen, zähler zurücksetzen                                             saveto.delete();                                             saveto = null;                                             loadedbytes = 0;                                             stop = false;                                         }                                         urlmd5 = datacontroller.geturlmd5(url.tostring());                                         filemd5 = datacontroller.getmd5(saveto.getcanonicalpath());                                         if(filemd5!=null && !filemd5.equals("")                                                  && urlmd5!=null && !urlmd5.equals("") && filemd5.equals(urlmd5))                                              // md5 correct                                         {                                             // finished-event auslösen                                             (downloadprogresslistener l: progresslisteners) {                                                 l.setchecksum("");                                                 l.setvalue(size);                                                 l.setstatus(downloadprogresslistener.status_finished);                                             }                                             viewcontroller.refreshmainprogress();                                              setrunning(false);                                         }else                                         { // error-md5                                             (downloadprogresslistener l: progresslisteners)                                              {                                                 l.setchecksum("");                                                 l.seterrormessage("error md5 incorrect: filemd5:'" + filemd5 + "' urlmd5:'" + urlmd5 + "'");                                                 l.setstatus(downloadprogresslistener.status_error);                                             }                                             viewcontroller.refreshmainprogress();                                              /*loadedbytes = 0;                                             retrycount++;                                             saveto.delete();                                             thread.sleep(1000);                                             if (retrycount < retrymax)                                              {                                                 startdownload();                                                 (downloadprogresslistener l: progresslisteners)                                                  {                                                     l.setstatus(downloadprogresslistener.status_running);                                                 }                                             }else                                             {                                                    datacontroller.getinstance().downloadsrunning.remove(url);                                                 loadedbytes = 0;                                                 retrycount = 0;                                                 outb.close();                                                 saveto.delete();                                             }*/                                         }                                 }                                 else {                                     // pause-event auslösen                                     (downloadprogresslistener l: progresslisteners) {                                         l.setstatus(downloadprogresslistener.status_paused);                                     }                                 }                               viewcontroller.refreshmainprogress();                              //}catch (interruptedexception e) {                             //  e.printstacktrace();                             } catch (sslexception e) {                                  try {                                     loadedbytes = 0;                                     retrycount++;                                     outb.close();                                     bos.close();                                     saveto.delete();                                      if (retrycount < retrymax) {                                         system.out.println("error: " + e.getlocalizedmessage() + "\n--> attempt #" + retrycount + ": retrying file '" + saveto.getname() + "' in 2 seconds.");                                          thread.sleep(2000); // 2s                                         startdownload();                                     } else {                                         // error-event auslösen                                         (downloadprogresslistener l: progresslisteners) {                                             l.seterrormessage("error retreiving network stream [" + e.getmessage() + "]");                                             l.setstatus(downloadprogresslistener.status_error);                                         }                                         loadedbytes = 0;                                         retrycount = 0;                                         outb.close();                                         bos.close();                                         saveto.delete();                                     }                                 } catch (exception e1) {                                     e1.printstacktrace();                                 }                             } catch (ioexception e) {                                 e.printstacktrace();                                  // error-event auslösen                                 (downloadprogresslistener l: progresslisteners) {                                     l.seterrormessage("error retreiving network stream [" + e.getmessage() + "]");                                     l.setstatus(downloadprogresslistener.status_error);                                 }                                  try {                                     loadedbytes = 0;                                     retrycount = 0;                                      // ausgabe- und netzwerk-stream beenden, zieldatei löschen                                     bos.flush();                                     bos.close();                                     bis.close();                                     outb.flush();                                     outb.close();                                     ins.close();                                     saveto.delete();                                 } catch (ioexception e1) {}                              } catch (securityexception e) {                                 e.printstacktrace();                                  loadedbytes = 0;                                 retrycount = 0;                                 // error-event auslösen                                 (downloadprogresslistener l: progresslisteners) {                                     l.seterrormessage("error accessing file '" + saveto.getabsolutepath() + "'");                                     l.setstatus(downloadprogresslistener.status_error);                                 }                             }                         }                 });                 downloadthread.start();             } else {                 string errmsg = "http error status: " + rc + " " + con.getresponsemessage();                 (downloadprogresslistener l: progresslisteners) {                     l.seterrormessage(errmsg);                     l.setstatus(downloadprogresslistener.status_error);                 }                  saveto.delete();                 loadedbytes = 0;                 retrycount = 0;             }         } catch (exception e) {             e.printstacktrace();              loadedbytes = 0;             retrycount = 0;             try {                 // ausgabe- und netzwerk-stream beenden                 bos.flush();                 bos.close();                 bis.close();                 outb.flush();                 outb.close();                 ins.close();             } catch (exception e1) {}              string errmsg = "unknown error";             if (e instanceof malformedurlexception) {                 errmsg = "invalid url";             } else if (e instanceof unknownhostexception) {                 errmsg = "unable resolve hostname '" + e.getmessage() + "'. please check network connection.";             } else if (e instanceof ioexception) {                 errmsg = e.getmessage(); //"error retreiving network stream";             }             system.out.println(errmsg);              // error-event auslösen             (downloadprogresslistener l: progresslisteners) {                 l.seterrormessage(errmsg);                 l.setstatus(downloadprogresslistener.status_error);             }                    }     } 

i not able reproduce error every time , seems machines produce more others. maybe false closed handle or that?

if resumed download , saved file isn't of expected length, if shorter, exist, have unhandled error case. don't know what's right situation wound deleting file , starting again.

and need make adjustments mentioned in comment, if clarity.


Comments

Popular posts from this blog

android - Get AccessToken using signpost OAuth without opening a browser (Two legged Oauth) -

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: mockito -

google shop client API returns 400 bad request error while adding an item -