2011-09-13 5 views
5

Je construis une application Android et j'ai besoin de télécharger un fichier à partir d'une URL, qui est de 33 Mo de large.Android: exception "fin de flux inattendue" téléchargement de gros fichiers

Ici, la tâche de téléchargement:

try { 
      int MAX_BUFFER_SIZE = 4096; 
      URL mUrl = new URL(params[0]); 
      HttpURLConnection connection = (HttpURLConnection) mUrl.openConnection(); 
      connection.setRequestMethod("GET"); 
      long length = connection.getContentLength(), downloaded = 0; 
      int read; 
      byte [] buffer = new byte[(((int)length) > MAX_BUFFER_SIZE) ? MAX_BUFFER_SIZE : (int)length]; 
      String filename = getFilename(mUrl); 
      File file = new File (SDCARD_ROOT); 
      if (!file.exists() || !file.isDirectory()){ 
       file.mkdir(); 
      } 
      this.filename = filename; 
      file = new File (SDCARD_ROOT + this.filename); 
      FileOutputStream fos = new FileOutputStream (file); 
      //Start downloading 
      InputStream stream = connection.getInputStream(); 

      while ((read=stream.read(buffer)) > -1){ 
       fos.write(buffer, 0, read); 
       downloaded += read; 
       publishProgress((int) ((float) downloaded/length * 100)); 
      } 
      fos.close(); 
      return 1; 
     } catch (Exception e){ 
      Log.e("REV-PARTS", "Revolver parts error in DownloadTask: " + e.getMessage()); 
      return 2; 
     } 

Il fonctionne bien avec les petits fichiers (1-15 Mo), mais il retournera une exception « fin inattendue du flux » avec de gros fichiers. Merci d'avance.

+0

Quel appel lève l'exception? 'stream.read()'? –

+1

Oui, stream.read – Gnufabio

+0

@Gnufabio avez-vous pu résoudre ce problème? –

Répondre

-2

pendant que vous attrapez l'exception, je tente la méthode downContinue(), je peux montrer mon code:

private void downloadApk() { 
    thread1 = new Thread() { 
     public void run() { 
      File oFile = null; 
      try { 
       URL url = new URL(PQGLApplication.resrootURL + "apk/PQGLMap.apk"); 
       HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); 
       ReadableByteChannel channel = 
         Channels.newChannel(urlConnection.getInputStream()); 
       oFile = 
         new File(Environment.getExternalStorageDirectory().getAbsolutePath() 
           + "/" + "hy_ht_new/" + "test2" + ".apk"); 
       oFile.setWritable(true); 
       oFile.setReadable(true); 
       if (oFile.exists()) { 
        oFile.delete(); 
       } 
       FileOutputStream fos = new FileOutputStream(oFile); 
       fileSize = urlConnection.getContentLength(); 
       ByteBuffer buffer = ByteBuffer.allocate(1024); 
       int noOfBytes = 0; 
       byte[] data = null; 
       sendApkMessage(0, 0); 
       while ((noOfBytes = channel.read(buffer)) > 0) { 
        data = new byte[noOfBytes]; 
        System.arraycopy(buffer.array(), 0, data, 0, noOfBytes); 
        buffer.clear(); 
        fos.write(data, 0, noOfBytes); 
        downLoadFileSize += noOfBytes; 
        sendApkMessage(1, downLoadFileSize); 
       } 
       fos.flush(); 
       fos.close(); 
       channel.close(); 
       sendApkMessage(2, oFile.getAbsolutePath()); 
      } catch (Exception e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
       downContinue(); 
      } 
     }; 
    }; 
    thread1.start(); 
} 

private void downContinue() { 
    continueTime++; 
    try { 
     if (continueTime == 3) { 
      continueTime = 0; 
      sendApkMessage(4, 0); 
      Log.e("what is the fucking continuetime", "continueTime" + continueTime); 
     } else { 
      URL url = new URL(PQGLApplication.resrootURL + "apk/PQGLMap.apk"); 
      HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); 
      File oFile = 
        new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/" 
          + "hy_ht_new/" + "test2" + ".apk"); 
      RandomAccessFile oSavedFile = new RandomAccessFile(oFile, "rw"); 
      FileOutputStream fos = new FileOutputStream(oFile); 
      ReadableByteChannel channel = Channels.newChannel(urlConnection.getInputStream()); 
      // oSavedFile.seek(nPos); 
      ByteBuffer buffer = ByteBuffer.allocate(1024); 
      byte[] data = null; 
      int temp = 0; 
      sendApkMessage(3, oFile.getAbsolutePath()); 
      while ((temp = channel.read(buffer)) > 0) { 
       data = new byte[temp]; 
       System.arraycopy(buffer.array(), 0, data, 0, temp); 
       buffer.clear(); 
       fos.write(data, 0, temp); 
      } 
      fos.flush(); 
      fos.close(); 
      oSavedFile.close(); 
      sendApkMessage(2, oFile.getAbsolutePath()); 
      continueTime = 0; 
     } 
    } catch (Exception e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
     Log.e("what is the fucking exception", e.toString() + continueTime); 
     downContinue(); 
    } 

} 

cette méthode de downContinue est utilisé pour résoudre ce problem.At moins, le fichier est téléchargé avec succès! Je viens de Chine.Mon anglais n'est pas si bon.

+0

pouvez-vous expliquer la méthode sendApkMessage(), que fait-il exactement? – skygeek

+0

Vous n'avez pas besoin de définir le fichier de sortie lisible ou inscriptible ou le pré-supprimer s'il existe. 'new FileOutputStream()' a déjà tous ces effets. Vous n'avez pas besoin de 'System.arraycopy()' non plus. La méthode repose sur un code externe non spécifié. – EJP

-1

Pour les fichiers volumineux, vous devez définir le délai de connexion manuellement en utilisant le code suivant. J'ai mis le temps à 3 minutes

connection.setConnectTimeout(180000); 
    connection.setReadTimeout(180000); 
+0

Comment cela résoudra-t-il un problème de «fin de flux inattendue»? – EJP

+0

ce sera comme cette erreur vient pendant le téléchargement en raison de timeout, –

0

j'ai une réponse pour cela. vous devriez ajouter un en-tête à votre connexion.

connection.setRequestProperty("Accept-Encoding", "identity"); 

cela vous aidera me you.say si elle aide ...

0

Définition d'une taille de bloc semblait fonctionner pour moi.

connection.setChunkedStreamingMode(1048576); 
Questions connexes