8
votes

Android: "Fin de flux inattendu" Exception en téléchargement de gros fichiers

Je construis une application Android et je dois télécharger un fichier à partir d'une URL, qui est 33 Mo de grande taille.

ici la tâche de téléchargement: p>

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;
        }


5 commentaires

Quel appel jette l'exception? flux.read () ?


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


L'expéditeur a fermé de manière inattendue la connexion. Rien que vous ne puissiez faire à ce sujet à cette fin, sauf supprimer le téléchargement partiel. NB Vous n'avez pas besoin de tout ce qui vous acheminant une taille de tampon. Il suffit d'utiliser 8192. Il n'y a aucun avantage de le relier à la taille des données. Votre code fonctionnera toujours.


Vous avez une réponse? pouvez-vous pu m'aider à m'aider pour ça


Cela semble un bogue dans l'émulateur Android pour Windows. MÊME WORKS FINILE INPLOY ET EMULATOIRE ANDROID sur Mac OS


4 Réponses :


-2
votes

Pendant que vous attrapez l'exception, j'essaie la méthode downcontinue () code>. 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 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 exception", e.toString() + continueTime);
        downContinue();
    }

}


2 commentaires

Pouvez-vous expliquer la méthode SendapkMessage (), qu'est-ce que c'est exactement?


Vous n'avez pas besoin de définir le fichier de sortie lisible ou inscriptible ou pré-supprimer s'il existe. Nouveau FileOutPutStream () a déjà tous ces effets. Vous n'avez pas besoin de système.arraycopy () non plus. Méthode s'appuie sur un code externe non spécifié.



-1
votes

Pour les fichiers volumineux, vous devez définir le délai de connexion manuellement à l'aide du code suivant. J'ai défini le temps sur 3 minutes xxx


3 commentaires

Comment cela va-t-il résoudre un problème de «fin inattendu du flux»?


Comme cette erreur va lors du téléchargement en raison du délai d'attente,


Non, ça ne va pas, et non ça ne le fait pas.



-1
votes

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

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


0 commentaires

-1
votes

Définir une taille de morceau semblait fonctionner pour moi. XXX


1 commentaires

N'aide-t-elle pas pour moi avec Android 9, obtenez toujours une "fin inattendue de flux"