2013-01-19 26 views
6

Chcę pobrać zapytanie HTTP z java, ale pobierany plik ma nieokreśloną długość podczas pobierania.Pobierz plik przez HTTP o nieznanej długości z Java

myślałem, że to byłoby dość standardowe, więc szukałem i znalazłem fragment kodu dla niego: http://snipplr.com/view/33805/

Ale ma problem ze zmienną contentLength. Ponieważ długość jest nieznana, otrzymuję -1 z powrotem. Powoduje to błąd. Kiedy pomijam całą kontrolę dotyczącą contentLength, oznacza to, że zawsze muszę używać maksymalnego bufora.

Problem polega na tym, że plik nie jest jeszcze gotowy. A więc kolor zostaje tylko częściowo wypełniony, a części pliku zostają zgubione.

Jeśli spróbujesz pobrać link, taki jak http://overpass-api.de/api/interpreter?data=area%5Bname%3D%22Hoogstade%22%5D%3B%0A%28%0A++node%28area%29%3B%0A++%3C%3B%0A%29+%3B%0Aout+meta+qt%3B z tym fragmentem, zauważysz błąd, a kiedy zawsze pobierzesz maksymalny bufor, aby pominąć błąd, otrzymasz uszkodzony plik XML.

Czy istnieje sposób na pobranie tylko gotowej części pliku? Chciałbym, żeby to mogło pobrać duże pliki (do kilku GB).

Odpowiedz

19

To powinno działać, ja testowałem to i działa dla mnie:

void downloadFromUrl(URL url, String localFilename) throws IOException { 
    InputStream is = null; 
    FileOutputStream fos = null; 

    try { 
     URLConnection urlConn = url.openConnection();//connect 

     is = urlConn.getInputStream();    //get connection inputstream 
     fos = new FileOutputStream(localFilename); //open outputstream to local file 

     byte[] buffer = new byte[4096];    //declare 4KB buffer 
     int len; 

     //while we have availble data, continue downloading and storing to local file 
     while ((len = is.read(buffer)) > 0) { 
      fos.write(buffer, 0, len); 
     } 
    } finally { 
     try { 
      if (is != null) { 
       is.close(); 
      } 
     } finally { 
      if (fos != null) { 
       fos.close(); 
      } 
     } 
    } 
} 

Jeśli chcesz tego, aby działać w tle, po prostu nazwać to w wątku:

Thread download = new Thread(){ 
    public void run(){ 
     URL url= new URL("http://overpass-api.de/api/interpreter?data=area%5Bname%3D%22Hoogstade%22%5D%3B%0A%28%0A++node%28area%29%3B%0A++%3C%3B%0A%29+%3B%0Aout+meta+qt%3B"); 
     String localFilename="mylocalfile"; //needs to be replaced with local file path 
     downloadFromUrl(url, localFilename); 
    } 
}; 
download.start();//start the thread 
+2

Dzięki, to działa . – sanderd17

+0

Zauważyłem, że prawdziwym problemem jest to, że polecenie file.seek nie działało poprawnie w tym przypadku. Nie znalazł końca pliku, a więc nadpisał jego część. Użycie pliku FileOutputStream naprawiło go (po usunięciu kodu błędu, tak jak już zrobiłem). – sanderd17