MokaByte
Numero 15 - Gennaio 1998
|
|||
|
|
||
Michele Sciabarrà |
|
||
Zip
in Java
Il JDK 1.1 comprende
un interessante ed utile package: java.util.zip. Come si può immaginare,
si tratta proprio delle classi necessarie per la gestione di archivi compressi
in formato ZIP standard. Il JDK 1.1 supporta il formato JAR di archiviazione
dei programmi in Java, che sono in realtà in formato ZIP. Niente
di strano quindi che internamente sia presente il supporto per i file ZIP.
Saggiamente quindi JavaSoft ha deciso di rendere disponibili delle classi
per l'uso generale del formato zip. Da notare che gli zip non sono interamente
gestiti in Java. Infatti tra le DLL del JRE (Java Runtime Environment)
esiste una zip.dll che chiaramente implementa in C le chiamate native necessarie
per la gestione degli ZIP. Si tratta, con tutta probabilità, di
codice derivato dalla versione freeware dello zip nota come Info-Zip.
In realtà
il supporto al formato ZIP non è completo. Lo ZIP prevede diversi
metodi di compressione, mentre è previsto il solo supporto per la
compressione deflating, che ha 9 livelli diversi di compressione, e per
lo storing senza compressione. Altresì è previsto il supporto
per la pura compressione deflating senza archiviazione ZIP, il formato
utilizzato dalla famora utility gzip, che come è noto non è
un archiviatore ma solo un compressore.
Si tratta comunque
di tutto e solo quello che è necessario in pratica: le altre forme
di compressione dello ZIP sono un residuo storico del PKZIP 1.0, mentre
il deflating è la compressione introdotta nel PKZIP 2.0 che è
la più efficiente in pratica. Più è alto il livello
di compressione, più il file finale è piccolo, ma più
la compressione è lenta.
In questo articolo
metteremo alla prova la gestione degli zip e ne impararemo l'uso, implementando
una piccola utility a linea di comando, jzip, che permette di listare,
scompattare e creare degli zip.
La sintassi
dell'utility (che ricorda quella del comando tar ) è:
InputStream in = zip.getInputStream(entry);
Una volta ottenuto
l'input stream, possiamo leggerlo e scriverlo in un file.
Per creare e
scrivere un file possiamo utilizzare un FileOutputStream: in teoria basterebbe
La classe jzip.JZip
Segue il codice di jzip.JZip, utilizzabile sia come utility a riga di comando che come classe utile in pratica per gestire in modo comodo i file zip
// Class: jzip.JZip
// Description: zip and unzip files given filenames
// Copyright: © 1997 Studio Satori
// Author: Michele Sciabarrà
package jzip;import java.util.*;
import java.util.zip.*;
import java.text.*;
import java.io.*;
public class JZip
{
static public
void main(String[] args)
throws java.io.IOException
{
if(args.length<2)
usage();
else if(args[0].startsWith("-t"))
list(args[1]);
else if(args[0].startsWith("-x"))
unzip(args[1]);
else if(args[0].startsWith("-c")) {
if(args.length < 3)
usage();
else {
String[] files = new String[args.length-2];
System.arraycopy(args, 2, files, 0, files.length);
zip(args[1], files);
}
} else
usage();
}
private static void usage()
{
System.out.println("usage:");
System.out.println("\tJZip -t <filename.zip>");
System.out.println("\t\tshow zip contents");
System.out.println("\tJZip -x <filename.zip>");
System.out.println("\t\textract files");
System.out.println("\tJZip -c <filename.zip> <files>..");
System.out.println("\t\tcreate a zip with files");
}
private static
void list(String filename)
throws IOException
{
ZipFile zip = new ZipFile(filename);
SimpleDateFormat fmt
= new SimpleDateFormat("yyyy.mm.dd hh:mm:ss");
Enumeration e = zip.entries();
System.out.println(" Size | Date | Name");
System.out.println("-----------+---------------------+--------------------------");
while(e.hasMoreElements()) {
ZipEntry entry = (ZipEntry)e.nextElement();
String sz = " "+entry.getSize();
sz = sz.substring(sz.length() - 10);
String tm = fmt.format(new Date(entry.getTime()));
System.out.println(sz+" | "+tm+" | "+entry.getName());
}
}
private static
void unzip(String filename)
throws IOException
{
final char sep = File.separatorChar;
byte[] buff = new byte[1024];
int m, n;
// for each file in zip
ZipFile zip = new ZipFile(filename);
Enumeration e = zip.entries();
while(e.hasMoreElements())
{
// get filename using local separator
ZipEntry entry = (ZipEntry)e.nextElement();
StringBuffer fixed = new StringBuffer(entry.getName());
for( int i = 0; i
if( fixed.charAt(i) == '/') fixed.setCharAt(i, sep);
File file = new File(fixed.toString());
// create dir
if(entry.isDirectory()) {
file.mkdirs();
continue;
}
String dir = file.getParent();
if( dir != null)
new File(dir).mkdirs();
// unzip file
System.out.println("unzipping: "+file);
OutputStream out = new FileOutputStream(file);
InputStream in = zip.getInputStream(entry);
while( (n = in.read(buff, 0, buff.length))!= -1)
out.write(buff, 0 , n);
}
}
private static
String[] recurse(String[] files, String dir)
{
final char sep = File.separatorChar;
Vector v = new Vector();
File file;
for(int i=0; i<files.length; ++i)
{
String filename = ( dir == null ? files[i]: dir+sep+files[i] );
file = new File( filename );
v.addElement(filename);
if( file.isDirectory()){
String[] res = recurse(file.list(), filename);
for( int j = 0; j<res.length; ++j)
v.addElement(res[j]);
}
}
String[] res = new String[v.size()];
v.copyInto(res);
return res;
}
private static
void zip(String filename, String[] files)
throws IOException
{
InputStream in;
int n;
// check
File zip = new File(filename);
if(zip.exists()) {
System.out.println("File "+filename+" already exist");
System.exit(1);
}
// open out file and write input files
String[] res = recurse(files, null);
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zip));
byte[] buff = new byte[1024];
for( int i = 0; i<res.length; ++i) {
File current = new File(res[i]);
if( current.isDirectory())
continue;
System.out.println("zipping: "+current);
out.putNextEntry(new ZipEntry(res[i]));
in = new FileInputStream(current);
while( (n = in.read(buff, 0, buff.length))!= -1)
out.write(buff, 0 , n);
in.close();
}
out.close();
}
}
|
||
MokaByte ricerca
nuovi collaboratori.
|
||
|