Upload e scompattamento di un allegato ZIP

di Andrea Bersi, in UserScript, ASP.NET, Upload,

Spesso si sente la necessità di effettuare un upload multiplo e l'operazione, com'è noto, non è possibile se non creando tanti campi di upload quanti sono i files che si vogliono spedire.
L'operazione diventa complessa se si devono spedire ad esempio 50 files o se non si conosce a priori il numero di files da inviare.
Per ovviare a questi problemi si può usare un piccolo stratagemma: inviare cioè al server un file ZIP che viene scompattato a destinazione raggiunta!
La logica sotto descritta è in grado di compattare solo file ZIP al cui interno siano presenti solo files e non cartelle.
Grazie ad una potente libreria open source, SharpZipLib, questa operazione è possibile con poche righe di codice.

Prima di tutto, seguiamo le istruzioni contenute nello script #282 per creare una maschera di upload.
Al pulsante associamo l'evento BtnUp_Click ed aggiungiamo una label denominata lblZIP che visualizzerà l'esito dell'operazione.

A questo punto, si inserisce il codice: è ovviamente necessario inserire riferimenti alla libreria e al Namespace System.IO che gestisce i files e le cartelle.

<%@ Register TagPrefix="ic" Namespace="ICSharpCode.SharpZipLib" Assembly="ICSharpCode.SharpZipLib, Version=0.5.0.0, Culture=neutral, PublicKeyToken=1b03e6acf1164f73" %>
<%@ import Namespace="ICSharpCode.SharpZipLib.Zip" %>
<%@ import Namespace="ICSharpCode.SharpZipLib.Checksums" %>
<%@ import Namespace="System.IO" %>

Si crea quindi l'evento associato al pulsante:

Sub BtnUp_Click(sender As Object, e As EventArgs)
  dim strFile as string
  strFile = inputFile.PostedFile.FileName
  'Ricavo il nome del file SENZA percorso.
  Dim strNomeFile as string
  strNomeFile = System.IO.Path.GetFileName(strFile)
  dim strPercorsoFileUpload as string
  strPercorsoFileUpload =server.mappath("/tempzip")
  'Effettuo UPLOAD
  inputFile.PostedFile.SaveAs( strPercorsoFileUpload & "\" & strNomeFile)
  'scompatta lo zip
  scompatta(strPercorsoFileUpload,strPercorsoFileUpload & "\" & strNomeFile,true,false)
End Sub

Il codice provvede a fare l'upload del file zip sul server, nella cartella indicata dalla variabile strPercorsoFileUpload (che è impostata su di una cartella denominata tempzip). Questa riga deve essere ovviamente personalizzata secondo le proprie esigenze.
L'ultima riga chiama la subroutine Scompatta che provvede a realizzare il lavoro più grosso.
La routine richiede due parametri obbligatori e due opzionali: i primi sono l'indirizzo della cartella di upload che deve essere assoluto (del tipo c:\inetpub\wwwroot\tuosito\cartellaxy) ed il secondo il nome, completo di path del file zippato, anche questo assoluto.
I due parametri opzionali, impostati di default su false, permettono, rispettivamente, di eliminare il file zip una volta terminata la scompattazione o di rinominare come .bak il file zippato e compresso sul server.
Nell'esempio, la chiamata alla funzione è tale da determinare la cancellazione del file.
È ovvio che non è possibile attribuire alla variabile rinomina il valore true se si è impostato elimina.
All'interno della routine, la variabile di testo denominata elencofile viene usata per creare una stringa, i cui elementi sono separati dal tag
, contenente i nomi dei files compattati; tale stringa viene quindi visualizzata nella label lblZIP prima descritta ad operazione ultimata.
Nel caso di errore, il codice provvede a segnalarlo nella stessa label il cui colore in primo piano viene impostato su rosso.

Public sub scompatta(ByVal cartella As String, _
             ByVal zipFic As String, _
             Optional ByVal elimina As Boolean = False, _
             Optional ByVal rinomina As Boolean = False) 

   Dim flag as boolean 'gestisce il corretto scompattamento
   dim fileName as string
   dim elencofile as string 'stringa di testo con all'interno i files scompattati

   If Not zipFic.ToLower.EndsWith(".zip") Then
     zipFic = Directory.GetFiles(zipFic, "*.zip")(0)
   End If

   Dim z As New ZipInputStream(File.OpenRead(zipFic))
   Dim theEntry As ZipEntry

   Do
     theEntry = z.GetNextEntry()
     If Not theEntry Is Nothing Then

       fileName  = cartella & "\" & Path.GetFileName(theEntry.Name)
       elencofile +=fileName +"<br>"
       Dim streamWriter As FileStream

       Try
         streamWriter = File.Create(fileName)
       Catch ex As DirectoryNotFoundException
         lblZIP.forecolor=drawing.color.fromname("Red")
         lblZIP.text="Errore!"
         flag=true
       End Try

       Dim size As Integer
       Dim data(2048) As Byte
       Do
         size = z.Read(data, 0, data.Length)
         If (size > 0) Then
           streamWriter.Write(data, 0, size)
         Else
           Exit Do
         End If
       Loop
       streamWriter.Close()
     Else
       Exit Do
     End If
   Loop
   z.Close()

   if not flag then
     lblZIP.forecolor=drawing.color.fromname("Green")
     lblZIP.text= "Scompattati:<BR>"+elencofile
   end if
   ' elimina se richiesto il file zip: default --> non elimina

   If elimina Then
     File.Delete(zipFic)
   End If
   ' rinomina se richiesto: default --> non rinomina
   If rinomina Then
     try
       File.delete (zipFic & ".bak")
     finally
       File.Copy(zipFic, zipFic & ".bak")
     end try
   End If

End Sub

Ovviamente il codice può essere variato, in particolare creando una function di cui gestire il risultato; potrebbe inoltre essere utile - o necessario a seconda dei casi - assicurarsi che venga effettivamente inviato un file compresso e non di altro tipo, come si può fare basandosi sullo script #446.

Approfondimenti


#282 - Upload con ASP.NET
https://www.aspitalia.com/liste/usag/script.aspx?ID=282

#446 - Upload con ASP.NET di immagini con controllo su content type, dimensione e larghezza/altezza
https://www.aspitalia.com/liste/usag/script.aspx?ID=446

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

I più letti di oggi