Creare un file zip in Java

Postato da ROb | nella categoria Java | giovedì, 4 marzo 2010

2

Già dalla versione 1.4 Java supporta la possibilità di creare file compressi di uno o più file.
L’algoritmo di compressione supportato è lo zip e le classi in gioco sono java.util.zip.ZipEntry e java.util.zip.ZipOutputStream.

File zip

La seguente funzione prende in input un file, che conterrà il nostro zip, e una lista di file.
All’interno del file zip inserirà tutti i file passati nel secondo parametro.

	private void createZip(File zipFile, List<File> files) throws IOException {
		FileOutputStream dest = null;
		ZipOutputStream out = null;

		byte data[] = new byte[BUFFER];

		try {
			dest = new  FileOutputStream(zipFile);
			out = new ZipOutputStream(new BufferedOutputStream(dest));

			if (files != null) {
				for (Iterator iter = files.iterator(); iter.hasNext();) {
					File file = null;
					FileInputStream fi = null;

					try {
						file = (File) iter.next();
						fi = new FileInputStream(file);

						/* add zip entry */
						ZipEntry entry = new ZipEntry(file.getName());
						out.putNextEntry(entry);

						int count;
						while ((count = fi.read(data, 0, BUFFER)) != -1) {
						   out.write(data, 0, count);
						}
					}
					catch (Exception e) {
						e.printStackTrace();
					}
					finally {
						fi.close();
					}
				}
			}
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		finally {
			out.close();
		}
	}

Come caricare un file sul server in AJAX

Postato da ROb | nella categoria Sviluppo web | martedì, 2 marzo 2010

2

I form html tradizionali negli anni hanno dimostrato numerosi limiti. Quelli più notevoli erano impossibilità di effettuare validazione server side, impossibilità di gestire dei campi autopopolati durante la digitazione, post completo del form senza possibilità di parzializzazione.

Ajax file upload

Tutte queste cose hanno reso il web uno strumento difficilmente utilizzabile per applicazioni che richiedessero un’elevata interazione con l’utente.
Negli ultimi anni AJAX ha rivoluzionato i tradizionali form html permettendo ai programmatori di poter dialogare agilmente con il loro backend e permettendo agli utenti di godere una più dinamica esperienza web.

Recentemente ho avuto la necessità di gestire un campo file in un form ajax. Per form ajax intendo un form che invia i suoi dati serializzati al server e non fa il post dell’intera pagina.
La tecnologia utilizzata era jQuery così ho cercato un plugin che si integrasse bene con tale tecnologia e ho trovato AJAX Upload.

Inseriamo innanzitutto gli script javascript nell’header necessari alla definizione di jQuery e del plugin AJAX Upload:

...
<head>
...
<script type="text/javascript" src="js/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="js/ajaxupload.js"></script>
...
</head>
...

A questo punto bisogna creare il div che cliccato avvierà la procedura di caricamento file:

<div id="upload_button">Upload</div>

Infine dobbiamo inizializzare i campi di tipo file all’interno del nostro form:

$(document).ready(function() {
    new AjaxUpload('upload_button_id', {action: 'uploadServletPath'});
}

Al rendering della pagina cliccando sul div upload_button si aprirà la finestra di dialogo per la scelta del file e il file sarà direttamente inviato via POST (senza però il POST dell’intera pagina) alla servlet di upload che abbiamo specificato nell’inizializzazione del componente.

Nel costruttore di inizializzazione possiamo anche passare altri parametri di configurazione e gestire alcuni eventi precedenti (o successivi) al caricamento utili per valorizzare altre variabili del form o per visualizzare la progressione del caricamento o il nome del file caricato sul server.
E’ anche possibile stabilire il tipo di risposta ricevuta dal server: html, xml o json.

Per chi fosse interessato ecco il codice Java necessario al salvataggio del file:

/*
 *	author: Roberto Rossi
 */
package it.bits4beats.servlets;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.*;
import java.util.Iterator;
import java.util.List;

public class UploadServlet extends HttpServlet {
	private static Log log = LogFactory.getLog(UploadServlet.class);
	public static final String DEFAULT_UPLOAD_DIR_INIT_PARAM = "DefaultUploadDir";

	/**
	 *
	 */
	private static final long serialVersionUID = 1L;

	/**
	 * This is a default constructor for UploadServlet class.
	 *
	 */
	public UploadServlet(){
	}

	public void init() throws ServletException {
		super.init();
	}

	/**
	 * Receive a file to be uploaded and save it into filesystem
	 */
	public void doGet(HttpServletRequest request,
			HttpServletResponse response)
	throws ServletException,java.io.IOException {
		log.info("method not supported!");
	}

	public void doPost(HttpServletRequest request,
			HttpServletResponse response)
	throws ServletException,java.io.IOException {

		String defaultUploadDir = getServletConfig().getInitParameter(DEFAULT_UPLOAD_DIR_INIT_PARAM);
		if (defaultUploadDir != null && !defaultUploadDir.equals("")) {
			log.debug("> default upload dir: " + defaultUploadDir);
		}

		/* the uploading user */
		String username = request.getParameter("username");
		/* max size of file upload */
		String sizeParam = request.getParameter("sz");
		Long maxBytes = null;
		if (sizeParam != null && !sizeParam.isEmpty()) {
			try {
				/* max 5Mb file uploaded */
				maxBytes = new Long(5242880);
			}
			catch (NumberFormatException nfe) {
				/* do nothing */
			}
		}

		log.debug("remote user: " + request.getRemoteUser());
		log.debug("user principal: " + (request.getUserPrincipal() == null ? "" : request.getUserPrincipal().getName()) );
		log.debug("username: " + username);

		String status = "true";
		String message = "";
		String savedfilename = "";
		String attachmentname = "";
		String originalFilename = "";

		/* reading file streams */
		boolean isMultipart = ServletFileUpload.isMultipartContent(request);

		if (isMultipart) {

			FileItemFactory factory = new DiskFileItemFactory();
			ServletFileUpload upload = new ServletFileUpload(factory);
			List items = null;
			try {
				items = upload.parseRequest(request);

				if (items != null && items.size() > 0) {

					File uploadDirFile = null;
					String uploadDirFileRelativePath = null;

					uploadDirFile = new File(getServletContext().getRealPath(defaultUploadDir));
					uploadDirFileRelativePath = defaultUploadDir;

					Iterator itr = items.iterator();

					FileItem fileItem = null;
					FileItem filenameItem = null;

					while(itr.hasNext()) {
						FileItem item = (FileItem) itr.next();

						if (!item.isFormField()) {
							fileItem = item;
						}
						else {
							if (item.getFieldName().equals("attachmentFilename")) {
								filenameItem = item;
								log.debug("filenameItem name: " + filenameItem.getFieldName() + " valore: " + filenameItem.getString());
							}
						}
					}

					if (fileItem != null) {
						/* there is a file item in the request */
						String fileName = fileItem.getName();
						log.debug("fileItem name: " + fileName);

						if (fileItem.getName().contains("\\")) {
							log.debug("Windows file");

							/* windows file path */
							fileName = fileItem.getName().substring(fileItem.getName().lastIndexOf("\\") +1);
							log.debug("fileItem name: " + fileName);
						}

						File fullFile  = new File(fileName);
						File savedFile = new File(uploadDirFile, fileName);

						if (savedFile != null) {

							/* check file size */
							if (maxBytes != null) {
								if (fileItem.getSize() > maxBytes.longValue()) {
									FileTooBigException ftbe = new FileTooBigException();
									ftbe.setMaxSize(new Long(maxBytes.longValue()/1024/1024).toString());
									throw ftbe;
								}
							}

							if (savedFile.exists()) {
								/* we need to create a file variant, save it and send it to the user */
								String fileNameWithoutExtension = savedFile.getName().substring(0, savedFile.getName().lastIndexOf("."));
								originalFilename = fileNameWithoutExtension;
								String suffix = savedFile.getName().substring(savedFile.getName().lastIndexOf(".") + 1);

								File newFile = File.createTempFile(fileNameWithoutExtension + "_", "." + suffix, uploadDirFile);
								fileItem.write(newFile);

								log.debug("newFile: " + newFile.getAbsolutePath());
								status = "true";
								message = "OK " + newFile.length() + " byte salvati";

								/* relative file path */
								savedfilename = uploadDirFileRelativePath + newFile.getName();
								String filenameWithExt =  extractFilenameWithExtensionFromPath(savedfilename);
								attachmentname = extractFilename(filenameWithExt);
							}
							else {
								log.debug("writing file to: " + savedFile.getAbsolutePath());
								originalFilename = extractFilename(extractFilenameWithExtensionFromPath(savedFile.getAbsolutePath()));
								fileItem.write(savedFile);

								status = "true";
								message = "OK " + savedFile.length() + " byte salvati";

								/* relative file path */
								savedfilename = uploadDirFileRelativePath + fullFile.getName();
								String filenameWithExt =  extractFilenameWithExtensionFromPath(savedfilename);
								attachmentname = extractFilename(filenameWithExt);
							}
						}
						else {
							log.error("cannot create file");
							status = "false";
							message = "Errore generico di salvataggio";
						}
					}

				}
				else {
					log.debug("no item to be saved");
				}
			}
			catch (FileTooBigException ftbe) {
				status = "false";
				message = "File troppo grande, dimensione massima (Mb): " + ftbe.getMaxSize();
			}
			catch (Exception e1) {
				e1.printStackTrace();
				log.error("error in uploading");

				status = "false";
				message = "Errore generico di salvataggio";
			}
		}

		PrintWriter out = response.getWriter();

		String responseMessage = "{\"success\":" + status + ",\"message\":\"" + message + "\",\"savedfilename\":\"" + savedfilename + "\",\"attachmentname\":\"" + attachmentname + "\",\"originalfilename\":\"" + originalFilename + "\"}";
		log.debug("responseMessage: " + responseMessage);
	    out.println(responseMessage);
	}

	/**
	 * This method extract filename (with extension) from filepath
	 *
	 * @param filepath
	 * @return filename without extension
	 */
	public static String extractFilenameWithExtensionFromPath(String filepath) {
		if (filepath != null) {
			int index = filepath.lastIndexOf("/");

			if (index > 0 && index < (filepath.length() -1)) {
				return filepath.substring(index + 1);
			}
			else return null;
		}
		else {
			return null;
		}
	}

	/**
	 * This method extract filename (without extension) from filename with extension
	 *
	 * @param filepath
	 * @return filename without extension
	 */
	public static String extractFilename(String filenameWithExtension) {
		if (filenameWithExtension != null) {
			int index = filenameWithExtension.lastIndexOf(".");

			if (index > 0) {
				return filenameWithExtension.substring(0, index);
			}
			else return filenameWithExtension;
		}
		else {
			return null;
		}
	}

	class FileTooBigException extends Exception {
		private static final long serialVersionUID = 1L;

		private String maxSize = null;

		public String getMaxSize() {
			return maxSize;
		}

		public void setMaxSize(String maxSize) {
			this.maxSize = maxSize;
		}

		public FileTooBigException() {
			super();
		}

		public FileTooBigException(String message) {
			super(message);
		}
	}

}

Nel sito del plugin trovate anche una demo completa e funzionante di AJAX upload.

Aggiungere un file di swap in un sistema Linux

Postato da ROb | nella categoria Linux | giovedì, 11 febbraio 2010

3

Chip di memoria

Se avete sottodimensionato la vostra partizione di swap potrebbe essere necessario aggiungere un file a tale partizione per fornire più memoria virtuale al vostro sistema.

Ecco i semplici passi da seguire per effettuare tale operazione:

  • loggarsi al sistema come utente root
  • lanciare il comando per creare il file di swap (in questo caso il file finale sarà di 512Mb):
    dd if=/dev/zero of=/newswapfile bs=1024 count=524288
    
  • impostare tale file come area di swap:
    mkswap /newswapfile
    
  • attivare il file di swap aggiungendolo all’attuale partizione di swap:
    swapon /newswapfile
    
  • modificare il file /etc/fstab per attivare il file di swap anche all’avvio del sistema. Aggiungere le seguenti righe:
    /newswapfile swap swap defaults 0 0
    
  • verificare che il file sia correttamente stato aggiunto alla partizione di swap. In particolar modo verificare la dimensione totale della swap area usando il comando:
    free -m
    

    oppure usando il comando htop:

    htop
    

Un hard drive online gratuito con Dropbox

Postato da ROb | nella categoria Informatica in generale, Linux | mercoledì, 27 gennaio 2010

0

Per quei pochi che ancora non conoscono questo servizio, oggi voglio parlarvi di Dropbox, il mio contenitore online di file preferito.

Negli anni passati mi ero abituato ad usare l’estensione Gspace per Firefox che permette di utilizzare lo spazio web di Gmail come fosse un server ftp. Un bel giorno però, girovagando qua e là nella rete, mi sono imbattuto in un post che parlava del servizio gratuito Dropbox. Come molti altri servizi del suo genere offre spazio gratuito online utilizzabile attraverso una comoda interfaccia web (uno tra questi e forse il più conosciuto è Box.net) ma a differenza di gran parte di essi Dropbox permette l’accesso anche tramite un client, anch’esso gratuito, disponibile sia per Linux che per Windows che per Mac.

Cartella Dropbox

Stuzzicato dall’idea di potervi accedere tramite Linux ho installato il client per la mia distribuzione, ho inserito le credenziali e sono diventato subito operativo.

Dropbox systray

Il client Linux di Dropbox si integra bene con il mio ambiente Gnome mettendomi a disposizione un’icona nella toolbar delle notifiche attraverso la quale posso accedere a tutte le principale funzioni del servizio.
Al primo avvio il programma chiede di specificare una directory utilizzata per la sincronizzazione con il servizio, dopodiché inizia a verificare eventuali file non sincronizzati ed eventualmente carica sul server o nel PC eventuali differenze riscontrate.
L’installazione avviene all’interno della home directory dell’utente e viene anche eseguito un demone, con l’avvio del computer, che monitorizza la directory per eventuali cambiamenti.

Dropbox dettaglio cartella pubblica

Un’altra funzione veramente utile è la possibilità di gestire una cartella pubblica all’interno della quale possiamo inserire dei file da rendere disponibili a tutti senza richiesta di credenziali particolari.
Dal menu contestuale di Nautilus (attivato dal file caricato) possiamo infine copiare l’indirizzo pubblico e inviarlo via mail o via IM ai nostri amici per il download diretto.

Per gli account free lo spazio a disposizione è di 2Gb, decisamente buono. Se si necessita di spazio ulteriore si può passare ad un account Pro e comprare il taglio di spazio necessario.