Visualizzazione dei risultati da 1 a 4 su 4

Discussione: Scaricare un file zip.

  1. #1
    Utente di HTML.it
    Registrato dal
    Mar 2006
    Messaggi
    47

    Scaricare un file zip.

    Sto lavorando a un app android ma la domanda riguarda java in generale.
    L'applicazione è l'equivalente dell' android market. Punto in qiestione: quando visualizzo i dettagli di una applicazione deve partire il download in background in modo che non mi si blocchi la gui. I file da scaricare sono file . zip di grandezza tra i 2 e 20 mega che salverò sulla mia sd.

    Il mio codice è il seguente che ammetto di aver in parte scopiazzato in rete perchè su questa parte sn carente e che sta dentro una classe ch estende service(che sn classi di android che girano in background ma cmq sullo stesso thread della gui)

    codice:
    if (mu.canReadFromExternalStorage()) //controlla che la sd sia legibile e scrivibile
    {
    	try 
    	{
                    URL url = new URL("http://62.101.121.49:8080/applicazioni/prova.zip");
    	        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    	        conn.setRequestMethod("GET");
    	        conn.setDoOutput(true);
    	        conn.setDoInput(true);
    	        conn.setRequestProperty("content-type", "binary/data");
    	        conn.connect(); //questa riga serve?
    		
                    File SDCardRoot =           Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOAD)
    // dove salverò il file
    	        boolean success = (SDCardRoot).mkdirs();// crea la directory se non c'è
    	        File file = new File(SDCardRoot,"prova.zip"); 
    			    
    	        file.createNewFile();// QUesta riga serve?
    		FileOutputStream fileOutput = new FileOutputStream(file,false);
    		InputStream inputStream = conn.getInputStream();
    		int totalSize = conn.getContentLength();
    		int downloadedSize = 0;
    		byte[] buffer = new byte[1024];
    		int bufferLength = 0; 
    		while ( (bufferLength = inputStream.read(buffer)) > 0 ) 
    		{
    		        fileOutput.write(buffer, 0, bufferLength);
    		        downloadedSize += bufferLength;
    		}
    		System.out.println("fato tutto chiudo");
    		fileOutput.close();
    		inputStream.close();
    		conn.disconnect();// Questa linea serve o meglio tenere la connessione aperta?
    		catch (MalformedURLException e) 
    		{
    		    e.printStackTrace();
    		} 
    		catch (IOException e) 
    		{
    		    e.printStackTrace();
    		}
    	}
    	else System.out.println("Non posso scrivere o legger dalla sd");
    }
    Domande:
    1)
    Volevo sapere è un approccio corretto sicuro e efficente per scaricare?
    Alcuni suggeriscono di usare un buffered streams. Il che suppongo voglia dire cambiare questa riga FileOutputStream fileOutput = new FileOutputStream(file,false);
    in
    qualcosa tipo new BufferedOutputStream(new FileOutputStream(file,false));
    Ma non mi è chiaro cosa cambie e che vantaggio ne abbia......

    2)Cosa cambia da uqanto sto facendo io a usare un socket????

    3)Alcune linee del codice sn commentate con "questa linea serve?" perchè se le tolgo non mi accorgo della differenza.........

    4)Quel che mi manca da fare è metter il tutto dentro un bel thread in modo che non si blocchi la gui mentre scarica.......dato però che io vorrei poter scaricare più file alla volta, ovvero ne faccio partire uno, poi intanto cerco una altra app e metto pure quella in download, c'è qualche cosa in più da fare o ogni volta ch creerò un nuovo thread questo farà tutto il lavoro sporco da se senza problemi?

    Grazie

  2. #2
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,328

    Re: Scaricare un file zip.

    Premetto che non ho mai usato il sistema Android, però per quanto riguarda Java:

    1)
    Volevo sapere è un approccio corretto sicuro e efficente per scaricare?
    Alcuni suggeriscono di usare un buffered streams. Il che suppongo voglia dire cambiare questa riga FileOutputStream fileOutput = new FileOutputStream(file,false);
    in
    qualcosa tipo new BufferedOutputStream(new FileOutputStream(file,false));
    Ma non mi è chiaro cosa cambie e che vantaggio ne abbia......
    Va benissimo anche così: la scrittura bufferizzata potrebbe darti dei vantaggi in termini di prestazione nel "download", perchè la scrittura vera sul supporto avviene solo quando il buffer interno dell'oggetto è pieno o viene effettuato un flush() o la chiusura dell'oggetto stesso, ma sono piccolezze.

    2)Cosa cambia da uqanto sto facendo io a usare un socket????
    In realtà, quando accedi ad una URL la Socket viene creata in automatico per te dal sistema, quindi... direi nulla.

    3)Alcune linee del codice sn commentate con "questa linea serve?" perchè se le tolgo non mi accorgo della differenza.........
    L'unica riga che vedo con quel commento è quella relativa alla chiusura della connessione. Da un punto di vista logico è sempre bene chiudere una connessione quando non è più usata. Più precisamente, però, sposterei quella riga dentro ad un blocco try/catch (necessario, per la chiamata al metodo close() ) incluso nella clausola finally del blocco più esterno, in modo che essa venga eseguita sempre anche in caso di eccezione avvenuta prima.
    Dal punto di vista pratico, non ti cambia nulla per il semplice fatto che la connessione viene chiusa automaticamente quando esci dal metodo in quanto l'oggetto URLConnection va fuori scope e viene marcato per il garbage collector... quindi, di fatto l'oggetto viene rimosso e la connessione viene chiusa automaticamene... ripeto: è sempre bene chiuderla a mano (nel finally).

    4)Quel che mi manca da fare è metter il tutto dentro un bel thread in modo che non si blocchi la gui mentre scarica.......dato però che io vorrei poter scaricare più file alla volta, ovvero ne faccio partire uno, poi intanto cerco una altra app e metto pure quella in download, c'è qualche cosa in più da fare o ogni volta ch creerò un nuovo thread questo farà tutto il lavoro sporco da se senza problemi?

    Grazie
    Sì, non devi fare altro che creare un thread che gestisce il download e avviarlo. La chiamata al metodo start() fa partire il thread e ritorna immediatamente, dandoti la possibilità di continuare con il tuo lavoro e lasciare libero l'EDT per la gestione della GUI.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  3. #3
    Utente di HTML.it
    Registrato dal
    Mar 2006
    Messaggi
    47
    Grazie mille ho spostato nel finally

    fileOutput.close();
    inputStream.close();

    mi viene ancora il dubbio sul metodo disconnect......perchè il download del file avviene sia
    che io faccia conn.connect() sia che non lo metta, quindi evidentemente qualche altro metodo che invoco lo chiama inplicitamemte.....ma il
    conn.disconnect(); serve?
    metto pure quello nel Finally?

  4. #4
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,328
    Originariamente inviato da Sgotenks
    Grazie mille ho spostato nel finally

    fileOutput.close();
    inputStream.close();

    mi viene ancora il dubbio sul metodo disconnect......perchè il download del file avviene sia
    che io faccia conn.connect() sia che non lo metta, quindi evidentemente qualche altro metodo che invoco lo chiama inplicitamemte.....
    Dalla documentazione del metodo connect() di URLConnection:

    Opens a communications link to the resource referenced by this URL, if such a connection has not already been established.

    If the connect method is called when the connection has already been opened (indicated by the connected field having the value true), the call is ignored.
    Quindi quel metodo serve a stabilire una connessione, se già non è stata instaurata precedentemente... richiamarlo su una URLConnection già connessa non ha alcun effetto.

    Può benissimo essere che la connessione sia già stata instaurata, ma metterlo non fa male.

    ma il
    conn.disconnect(); serve?
    metto pure quello nel Finally?
    Io parlavo proprio di quello, non avevo visto il commento sulla connect, alla quale ho risposto ora.

    Sì, la disconnect andrebbe messa nel finally.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.