2010-10-28 19 views
4

Je suis en train de télécharger un fichier zip qui est juste inférieur à 22 mb au démarrage. J'ai changé le BufferedInputStream par défaut après ces exceptions, mais toujours obtenir une erreur de mémoire insuffisante.Android télécharger le fichier hors de la mémoire malheurs

public void downloadFromUrl(String fileName) { 

     //avoid unknown host exception 
     try { 

      InetAddress i = InetAddress 

        .getByName("http://xxx/Android/" + fileName); 

     } catch (UnknownHostException e1) { 

      e1.printStackTrace(); 

     } 

     try { 

      URL url = new URL("http://xxx/Android/" + fileName); 
      File file = new File(fileName); 

      long startTime = System.currentTimeMillis(); 
      Log.d("DownloadManager", "download begining"); 
      Log.d("DownloadManager", "download url:" + url); 
      Log.d("DownloadManager", "downloaded file name:" + fileName); 

      URLConnection ucon = url.openConnection(); 

      InputStream is = ucon.getInputStream(); 
      BufferedInputStream bis = new BufferedInputStream(is, 23 * 1024); 

      ByteArrayBuffer baf = new ByteArrayBuffer(23 * 1024); 
      int current = 0; 
      while ((current = bis.read()) != -1) { 

       baf.append((byte) current); 

      } 

      FileOutputStream fos = new FileOutputStream(file); 
      fos.write(baf.toByteArray()); 
      fos.close(); 
      Log.d("DownloadManager", 
        "download ready in" 
          + ((System.currentTimeMillis() - startTime)/1000) 
          + " sec"); 

     } catch (IOException e) { 

      Log.d("DownloadManager", "Error: " + e); 

     } 

    } 

pile:

10-28 10:18:16.885: DEBUG/ImageManager(1804): download begining 
10-28 10:18:16.885: DEBUG/ImageManager(1804): download url:http://xxx/Android/Samples.zip 
10-28 10:18:16.885: DEBUG/ImageManager(1804): downloaded file name:Samples.zip 
10-28 10:18:17.204: INFO/global(1804): Default buffer size used in BufferedInputStream constructor. It would be better to be explicit if an 8k buffer is required. 
10-28 10:18:17.845: DEBUG/dalvikvm(1804): GC_FOR_MALLOC freed 1803 objects/185168 bytes in 96ms 
10-28 10:18:18.415: DEBUG/dalvikvm(1804): GC_FOR_MALLOC freed 229 objects/105296 bytes in 78ms 
10-28 10:18:18.425: INFO/dalvikvm-heap(1804): Grow heap (frag case) to 3.184MB for 376848-byte allocation 
10-28 10:18:18.545: DEBUG/dalvikvm(1804): GC_FOR_MALLOC freed 0 objects/0 bytes in 109ms 
10-28 10:18:20.555: DEBUG/dalvikvm(1804): GC_FOR_MALLOC freed 44 objects/190080 bytes in 65ms 
10-28 10:18:20.575: INFO/dalvikvm-heap(1804): Grow heap (frag case) to 3.721MB for 753680-byte allocation 
10-28 10:18:20.675: DEBUG/dalvikvm(1804): GC_FOR_MALLOC freed 0 objects/0 bytes in 95ms 
10-28 10:18:22.725: DEBUG/dalvikvm(1804): GC_FOR_MALLOC freed 3 objects/376904 bytes in 66ms 
10-28 10:18:23.145: INFO/dalvikvm-heap(1804): Grow heap (frag case) to 4.799MB for 1507344-byte allocation 
10-28 10:18:23.245: DEBUG/dalvikvm(1804): GC_FOR_MALLOC freed 0 objects/0 bytes in 95ms 
10-28 10:18:25.415: WARN/ActivityManager(59): Launch timeout has expired, giving up wake lock! 
10-28 10:18:26.205: WARN/ActivityManager(59): Activity idle timeout for HistoryRecord{43ef1378 com.xxx.xxxe/.TabViewMain} 
10-28 10:18:27.995: DEBUG/dalvikvm(1804): GC_FOR_MALLOC freed 3 objects/753736 bytes in 65ms 
10-28 10:18:28.655: INFO/dalvikvm-heap(1804): Grow heap (frag case) to 6.956MB for 3014672-byte allocation 
10-28 10:18:28.765: DEBUG/dalvikvm(1804): GC_FOR_MALLOC freed 0 objects/0 bytes in 102ms 
10-28 10:18:33.275: DEBUG/dalvikvm(123): GC_EXPLICIT freed 833 objects/48984 bytes in 2059ms 
10-28 10:18:37.275: DEBUG/dalvikvm(1804): GC_FOR_MALLOC freed 3 objects/1507400 bytes in 69ms 
10-28 10:18:38.115: INFO/dalvikvm-heap(1804): Grow heap (frag case) to 11.268MB for 6029328-byte allocation 
10-28 10:18:38.275: DEBUG/dalvikvm(1804): GC_FOR_MALLOC freed 0 objects/0 bytes in 151ms 
10-28 10:18:53.885: DEBUG/dalvikvm(1804): GC_FOR_MALLOC freed 3 objects/3014728 bytes in 70ms 
10-28 10:18:53.895: INFO/dalvikvm-heap(1804): Forcing collection of SoftReferences for 12058640-byte allocation 
10-28 10:18:54.055: DEBUG/dalvikvm(1804): GC_FOR_MALLOC freed 0 objects/0 bytes in 158ms 
10-28 10:18:54.055: ERROR/dalvikvm-heap(1804): Out of memory on a 12058640-byte allocation. 

EDIT: Ok, j'ai pu obtenir this example travail, mais même avec les autorisations correctes, je reçois une erreur de permission refusée:

`10-2`8 11:33:15.478: WARN/System.err(1781): java.io.FileNotFoundException: /mnt/sdcard/testDirectory/Samples.zip (Permission denied) 
+1

Pourquoi le télécharger entièrement dans le RAM? Je pense que vous n'êtes pas très familier avec java.io. En d'autres termes, votre question n'est pas spécifique à Android. –

+0

Définitivement nouveau à Java, apprenant encore ce que signifie quoi. Je n'ai pas réalisé que le ByteArrayBuffer était en train d'être envoyé en RAM, je pensais qu'il était envoyé à SD! –

Répondre

6

Pas étonnant, vous essayez de créer un bytear de 22 Mo dans la mémoire vive de votre téléphone; La plupart des téléphones Android n'ont pas beaucoup de RAM. Ce que vous voulez faire est de diffuser le fichier sur la carte SD ou le stockage interne:

// untested 
final int BUFFER_SIZE = 23 * 1024; 
InputStream is = ucon.getInputStream(); 
BufferedInputStream bis = new BufferedInputStream(is, BUFFER_SIZE); 
FileOutputStream fos = new FileOutputStream(file); 
byte[] baf = new byte[BUFFER_SIZE]; 
int actual = 0; 
while (actual != -1) { 
    fos.write(baf, 0, actual) 
    actual = bis.read(baf, 0, BUFFER_SIZE); 
} 

fos.close(); 
+0

Hmmm ... cela me donne une exception java.io.file non trouvée (système de fichiers en lecture seule). –

+0

@ user375566: assurez-vous que votre application dispose des autorisations appropriées pour écrire des fichiers http://developer.android.com/guide/topics/security/security.html et vous devez décider si vous voulez un stockage interne ou un stockage externe http: // developer.android.com/guide/topics/data/data-storage.html –

+0

J'utilise external, et je pense avoir toutes les permissions nécessaires. –

1

Pourquoi utilisez-vous un ByteArrayBuffer? C'est le problème, vous essayez de stocker 22mb dedans.

4

Voici une petite méthode pour télécharger de gros fichiers testés inspiré par Lie Ryan (merci à lui) en utilisant FileOutputStream pour vider le tampon.

public void DownloadFromUrl(String fileURL, String fileName) { //this is the downloader method 
     try { 
       URL url = new URL(fileURL); 
       File file = new File(fileName); 
       file.createNewFile(); 
       long startTime = System.currentTimeMillis(); 
       Log.d("DownloadManager", "download begining"); 
       Log.d("DownloadManager", "download url:" + url); 
       Log.d("DownloadManager", "downloaded file name:" + fileName); 
       /* Open a connection to that URL. */ 
       URLConnection ucon = url.openConnection(); 

       /* 
       * Define InputStreams to read from the URLConnection. 
       */ 
       InputStream is = ucon.getInputStream(); 

       /* 
       * Read bytes to the Buffer until there is nothing more to read(-1) and write on the fly in the file. 
       */ 
       FileOutputStream fos = new FileOutputStream(file); 
       final int BUFFER_SIZE = 23 * 1024; 
       BufferedInputStream bis = new BufferedInputStream(is, BUFFER_SIZE); 
       byte[] baf = new byte[BUFFER_SIZE]; 
       int actual = 0; 
       while (actual != -1) { 
        fos.write(baf, 0, actual); 
        actual = bis.read(baf, 0, BUFFER_SIZE); 
       } 

       fos.close(); 
       Log.d("DownloadManager", "download ready in" 
           + ((System.currentTimeMillis() - startTime)/1000) 
           + " sec"); 

     } catch (IOException e) { 
       Log.d("DownloadManager", "Error: " + e); 
     } 

}