
guide
Tutti i linguaggi per diventare uno sviluppatore di app per Android.
Selezioniamo dei file presenti in remoto, per creare un file zip, e diamo la possibilità all’utente di poter fare il download.
In un precedente articolo abbiamo visto come organizzare e gestire una struttura a directory fisicamente residente su un disco remoto.
A partire da quel semplice esempio è possibile effettuare delle operazioni più complesse, basate sulle esigenze delle applicazioni che ogni volta dovremo progettare.
In questo articolo estenderemo il funzionamento dell’applicativo con la funzione di zip del contenuto di una directory remota e successivo download verso l’utente.
Attraverso l’esempio che metteremo in atto vedremo come sia possibile selezionare un insieme di file residenti sul server, zippare gli stessi ed eseguire il download verso l’utente che ne ha fatto richiesta. Riusciremo a fare questo in maniera semplice grazie alla presenza delle librerie java.util.zip
, che forniscono le funzionalità di base per effettuare le operazioni di zip e unzip. Infine prenderemo spunto da queste per discutere del meccanismo di base fornito da java per le operazioni di scrittura e lettura di flussi informativi.
Le possibilità che vedremo nell’esempio sono molteplici, soprattutto per le web application che permettono il download di file e garantiscono facilità di gestione nel download, diminuendo la banda utilizzata (grazie allo zip) e diminuendo la difficoltà nel gestire differenti download (grazie all’unione dei file da scaricare in un singolo file).
Un buon esempio che si potrebbe fare è per portali di e-commerce che vendono prodotti attraverso il download, magari la vendita di musica online. Attraverso questa operazione, in seguito alla scelta dei brani in un carrello della spesa, gli stessi verranno compattati e scaricati sul computer dell’utente che li acquista.
Come già accennato, l’operazione fa uso del package java.util.zip che implementa classi e metodi per la lettura e la scrittura di file nei formati ZIP e GZIP secondo gli standard vigenti.
Quello di cui ci dobbiamo preoccupare è quindi di creare l’algoritmo sulla base delle classi di questo package.
Riprendendo l’esempio dello scorso articolo, estendiamo l’interfaccia, aggiungendo un ulteriore metodo che si aspetta un’array di file in ingresso, il nome utente e la directory dove recuperare i file.
La logica del metodo sarà: compattare i file contenuti nell’array e restituire il file al chiamante (nel nostro caso, la servlet, a cui viene delegate il compito del download).
Più interessante è l’implementazione del metodo, a partire dalla quale potrete implementare al meglio i vostri specifici servizi.
Listato 1. Crea lo zip dei file selezionati e lo fa scaricare all’utente
//FileManagerConcrete.java
..//
public File mkZip(File[]files,String user,String dir) throws IOException{
//Creazione del path
String directory=root+File.separator+user;
//se DIR è vuoto, ci troviamo nella directory root
if (dir!=null && !dir.equals(“”))
directory+=File.separator+dir;
//File name: root/dir/user.zip
String filename=directory+File.separator+user+”.zip”;
//Creazione dello stream di scrittura
File file=new File(filename);
FileOutputStream fileZip=new FileOutputStream(file);
//Decoro lo stream di output con il filtro di Zip
ZipOutputStream zip=new ZipOutputStream(fileZip);
//Ogni entry della collection rappresenta un file, che aggiungiamo allo zip
for(int i=0;i<files.length;i++){
File f=(File)files[i];
//File name: root/dir/filexyz.000
addFileEntry(f,zip);
}
//Chiusura dei flussi aperti
zip.finish();
fileZip.close();
/**
* Se è andato tutto bene restituiamo il path dove scaricare il file fisico
* creato lato server.
*/
return file;
}
/**
* Aggiunge un file allo stream ZIP
*/
private void addFileEntry(File file, ZipOutputStream zip) throws IOException {
ZipEntry item=new ZipEntry( file.getName() );
/**
* RandomAccessFile è una virtualizzazione per accedere ad un file,
* in questo caso accediamo in sola lettura: attraverso questa classe si
* possono recuperare proprietà “ad accesso casuale” come la lunghezza del file
*/
if (!file.isDirectory()){
RandomAccessFile f=new RandomAccessFile(file,”r”);
//Lettura del contenuto del file e salvataggio come item nello zip
byte []buffer=new byte[(int) f.length()];
f.read(buffer);
zip.putNextEntry(item);
//Scrittura del contenuto del file
zip.write(buffer,0,(int) f.length());
zip.closeEntry();
}
}
..//
Nella parte iniziale ci preoccupiamo di creare il path fisico dove temporaneamente verrà memorizzato il file zip. Apriamo un flusso di scrittura (output stream) su tale file al quale agganciamo il filtro ZipOutputStream
. Dentro questo stream inseriremo una voce per ogni file presente nell’array, attraverso il metodo addFileEntry()
: la classe ZipEntry
virtualizza ogni singola voce del file zip, il metodo ZipOutputStream.write()
scrive fisicamente il contenuto zippato del file in questione.
Alla fine del ciclo chiudiamo i flussi aperti e restituiamo il file appena zippato.
La classe client di questo FileManager, chiamando il suddetto metodo, si troverà come ritorno il file zippato, su cui effettuare delle operazioni: nel nostro caso la servlet dovrà inoltrare il file all’utente sotto forma di download e poi eliminarlo fisicamente dal disco.
Listato 2. Invia il file all’utente e poi lo cancella dal disco fisso
//Dispatcher.java
..//
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
String op=req.getParameter(“op”);
..//
if (op.equals(“zip”)){
doZip(req,resp);
}
}
private void doZip(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
//Recupero dei parametri attesi ed esecuzione della funzione
String user=req.getParameter(“user”);
String dir=req.getParameter(“dir”);
//Recupero la lista di files della directory
File[] files=fm.getFileList(user,dir);
//Zippo la lista di file e inoltro il browser verso il file da scaricare
File zip=fm.mkZip(files,user,dir);
/**
* Settiamo la tipologia di file ricevuta dall’utente
* e la sua dimensione attesa
*/
resp.setContentLength((int) zip.length());
resp.setContentType(“application/zip”);
/**
* Procedura di buffering: leggo il contenuto, lo memorizzo in una
* struttura dati temporanea e lo inoltro sulla rete.
*/
FileInputStream fis=new FileInputStream(zip);
byte buffer[]=new byte[4096];
int read=0;
while( (read=fis.read(buffer))>0){
resp.getOutputStream().write(buffer,0,read);
}
//Chiusura dello stream e cancellazione del file
resp.getOutputStream().close();
fis.close();
zip.delete();
}
..//
Il metodo della servlet che si occupa di effettuare l’operazione di zip e download, utilizza lo strato di logica presente nel FileManager, richiamandone il metodo sopra esposto. Per il download, invece, verrà effettuata un’operazione che ci ritroveremo spesso operando sui flussi di java.
In pratica si apre un flusso di lettura su un canale (il disco fisso, attraverso FileInputStream
) e uno di scrittura su un altro canale (la rete, attraverso il metodo getOutputStream()
della servlet che restituisce un ServletOutputStream
): leggendo il contenuto dal primo e scrivendo sul secondo effettueremo l’operazione di download del file.
Come si vede, il secondo oggetto è recuperato a partire dall’oggetto HttpServletResponse resp
, che virtualizza il canale di ritorno verso l’utente, quindi, di fatto, la scrittura avviene su un processo di rete residente su una macchina client.
Per ottimizzare l’operazione abbiamo usato un buffer di lettura di 4 KB, ma sarebbe bene dimensionarlo in base a diversi parametri (banda disponibile, su tutti).
Per concludere, mostriamo come tale operazione viene richiamata dalle pagine JSP (nel nostro caso, dalla view che elenca i file disponibili in una directory).
Listato 3. JSP che richiama il processo di zip e download
//List.jsp
..//
<h1>Lista file: <%=dir%></h1>
<hr/>
..//
<hr/>
<!–
Attraverso il link si esegue la funzione di ZIP e DOWNLOAD della directory
–>
<p>
<a href=”action?op=zip&user=<%=request.getParameter(“user”)%>&dir=<%=request.getParameter(“dir”)%>”>Zippa il contenuto della directory e download.</a>
</p>
..//
Attraverso un ipertesto, con i parametri opportunamente settati, rimandiamo alla funzione sulla servlet, che ci restituirà il download del contenuto zippato della directory che stiamo visualizzando. L’algoritmo che abbiamo mostrato può essere applicato in base alle esigenze che ogni volta si avranno, indipendentemente dall’applicazione. Come si vede dalla “signature” del metodo, il fatto che accetti come parametri di ingresso un array di file, la rende disponibile a qualsiasi uso ne dovrete fare in tutta l’applicazione.
Se vuoi aggiornamenti su Zippare ed effettuare il download di file da remoto inserisci la tua email nel box qui sotto:
Compilando il presente form acconsento a ricevere le informazioni relative ai servizi di cui alla presente pagina ai sensi dell'informativa sulla privacy.
La tua iscrizione è andata a buon fine. Se vuoi ricevere informazioni personalizzate compila anche i seguenti campi opzionali:
Compilando il presente form acconsento a ricevere le informazioni relative ai servizi di cui alla presente pagina ai sensi dell'informativa sulla privacy.
L’esperienza di uno startupper
Tutti i linguaggi per diventare uno sviluppatore di app per Android.
Come creare applicazioni per il Web con PHP e MySQL per il DBMS.
Tutte le principali tecnologie per diventare uno sviluppatore mobile per iOS.
I fondamentali per lo sviluppo di applicazioni multi piattaforma con Java.
Diventare degli esperti in tema di sicurezza delle applicazioni Java.
Usare Raspberry Pi e Arduino per avvicinarsi al mondo dei Maker e dell’IoT.
Le principali guide di HTML.it per diventare un esperto dei database NoSQL.
Ecco come i professionisti creano applicazioni per il Cloud con PHP.
Lo sviluppo professionale di applicazioni in PHP alla portata di tutti.
Come sviluppare applicazioni Web dinamiche con PHP e JavaScript.
Fare gli e-commerce developer con Magento, Prestashop e WooCommerce.
Realizzare applicazioni per il Web utilizzando i framework PHP.
Creare applicazioni PHP e gestire l’ambiente di sviluppo come un pro.
Percorso base per avvicinarsi al web design con un occhio al mobile.
Realizzare siti Web e Web application con WordPress a livello professionale.
Iniziamo ad utilizzare il framework per web application ZK, creando un semplice “Hello World” in ZK Studio.
Breve panoramica che illustra le principali caratteristiche delle servet 3.0, con esempi
UrlRewriteFilter: emulare mod_rewrite in Java
Impariamo a sviluppare applicazioni Java per i sistemi Embedded, piattaforme che a differenza delle tradizionali soluzioni general purpose vengono progettate per svolgere compiti specifici. Nel corso delle guida verranno fornite le nozioni necessarie per installare Oracle Java SE Embedded, scegliere il profilo e la JVM da utilizzare, configurare una JRE personalizzata, creare una prima App ed effettuarne il deploy