fr.lixbox.common.stream.util.ZipUtil Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of lixbox-stream Show documentation
Show all versions of lixbox-stream Show documentation
Ce dépôt contient le code de la librairie lixbox-stream
The newest version!
/*******************************************************************************
*
* FRAMEWORK Lixbox
* ==================
*
* This file is part of lixbox-common.
*
* lixbox-iam is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* lixbox-iam is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with lixbox-common. If not, see
*
* @AUTHOR Lixbox-team
*
******************************************************************************/
package fr.lixbox.common.stream.util;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.Adler32;
import java.util.zip.CheckedOutputStream;
import java.util.zip.Deflater;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import fr.lixbox.common.util.StringUtil;
/**
* Cette classe fournit un utilitaire servant a creer, modifier une archive ZIP.
*
* @author ludovic.terral
*/
public class ZipUtil
{
private static final String PATH_SEPARATOR = "/";
// ----------- Attribut -----------
protected static final Log LOG = LogFactory.getLog(ZipUtil.class);
protected static final int BUFFER = 2048;
private static final String CHECKSUM = "checksum: ";
private static final String EXTRACTION_PATH = "/extraction";
private File fichier = null;
private FileOutputStream dest;
private CheckedOutputStream checksum;
private BufferedOutputStream buff;
private ZipOutputStream out;
// ----------- Methode -----------
public ZipUtil(String cheminArchiveZip)
{
fichier = new File(cheminArchiveZip);
}
public ZipUtil(File archiveZip)
{
fichier = archiveZip;
}
/**
* Cette methode affiche les informations de
* l'archive
*/
public String afficherDetail()
{
StringBuilder sbf = new StringBuilder("Archive ");
try(ZipFile archive = new ZipFile(fichier);)
{
String method = null;
sbf = new StringBuilder("Archive " + archive.getName() + System.getProperty("line.separator"));
final Enumeration> entries = archive.entries();
final DateFormat df = new SimpleDateFormat("yyyy/mm/dd_hh:mm:ss");
// parcours des entrees
while (entries.hasMoreElements())
{
ZipEntry e = ((ZipEntry) entries.nextElement());
Date d = new Date(e.getTime());
if (e.getMethod() == ZipEntry.DEFLATED)
{
method = "DEFLATED";
}
sbf.append(e.getName() + ", ");
sbf.append(e.getComment() + ", ");
sbf.append(e.getCompressedSize() + " octets, ");
sbf.append("CRC:" + e.getCrc() + ", ");
sbf.append(String.valueOf(e.getExtra()) + ", "); // $codepro.audit.disable improperConversionOfArrayToString
sbf.append(method + ", ");
sbf.append(e.getSize() + " octets, ");
sbf.append(df.format(d) + ", ");
sbf.append(e.hashCode() + ", ");
if (!e.isDirectory())
{
sbf.append(("ratio: " + (((e.getSize() - e.getCompressedSize()) * 100) / e.getSize())) + "%");
}
}
}
catch (IOException e)
{
LOG.fatal(e);
}
return sbf.toString();
}
/**
* Cette methode ajoute un ou plusieurs fichers dans
* l'archive
*
* @param fichiersOuRepertoire
*
* @return true si integration ok
* false si echec
*/
public boolean ajouterUnOuDesFichiers(File fichiersOuRepertoire)
{
boolean result;
try
{
result = preparerArchive();
//ajout des nouveaux fichiers
try
{
ajouterFichier(out, fichiersOuRepertoire, "");
}
catch (Exception e)
{
LOG.fatal(e);
result=false;
}
out.close();
buff.close();
checksum.close();
dest.close();
LOG.debug(CHECKSUM + checksum.getChecksum().getValue());
result = true;
}
catch (Exception e)
{
LOG.fatal(e);
result=false;
}
return result;
}
/**
* Cette methode ajoute un fichier de type texte dans
* l'archive ZIP
*
* @param nomFichier
* @param data
* @param charset
*
* @return true si l'integration est ok
* false dans les autres cas
*/
public boolean ajouterFichierTexte(String nomFichier, String data, Charset charset)
{
boolean result;
try
{
result = preparerArchive();
//ajouter le fichier texte
try
{
ZipEntry entry = new ZipEntry(nomFichier);
out.putNextEntry(entry);
StreamStringUtil.write(data, out, charset);
}
catch (Exception e)
{
LOG.fatal(e);
result=false;
}
out.close();
buff.close();
checksum.close();
dest.close();
LOG.debug(CHECKSUM + checksum.getChecksum().getValue());
result = true;
}
catch (Exception e)
{
LOG.fatal(e);
result=false;
}
return result;
}
/**
* Cette methode ajoute un fichier dans l'archive ZIP
*
* @param nomFichier
* @param data
*
* @return true si l'integration est ok
* false dans les autres cas
*/
public boolean ajouterFichier(String nomFichier, byte[] data)
{
boolean result;
try
{
result = preparerArchive();
//ajouter le fichier texte
try
{
ZipEntry entry = new ZipEntry(nomFichier);
out.putNextEntry(entry);
out.write(data);
out.closeEntry();
}
catch (Exception e)
{
LOG.fatal(e);
result=false;
}
out.close();
buff.close();
checksum.close();
dest.close();
LOG.debug(CHECKSUM + checksum.getChecksum().getValue());
result = true;
}
catch (Exception e)
{
LOG.fatal(e);
result=false;
}
return result;
}
/**
* Cette methode extrait un ficher de l'archive
*
* @param destination
*
* @return true si l'extraction est ok
* flase si echec
*/
public boolean extraireLesFichiers(File destination)
{
boolean result = true;
try
(
FileInputStream fis = new FileInputStream(fichier);
BufferedInputStream buffi= new BufferedInputStream(fis);
ZipInputStream zis= new ZipInputStream(buffi);
)
{
//creation de la destination
if (!destination.exists())
{
result &= destination.mkdirs();
}
//extraction
ZipEntry entry = null;
// parcours des entrees de l'archive
while (null != (entry = zis.getNextEntry()))
{
LOG.debug("Extracting: " + entry);
int count=0;
byte[] data = new byte[BUFFER];
//creation de l'arborescence si necessaire
String chemin = StringUtils.left(entry.getName(), entry.getName().lastIndexOf('/'));
if (!StringUtil.isEmpty(chemin) && !new File(destination.getAbsolutePath() + PATH_SEPARATOR + chemin).exists())
{
result &= new File(destination.getAbsolutePath() + PATH_SEPARATOR + chemin).mkdirs();
}
//ecriture des fichiers
if (!entry.getName().endsWith(PATH_SEPARATOR))
{
try (
FileOutputStream fos = new FileOutputStream(destination.getAbsolutePath() + PATH_SEPARATOR + entry.getName());
BufferedOutputStream desti = new BufferedOutputStream(fos, BUFFER);
)
{
while ((count = zis.read(data, 0, BUFFER)) != -1)
{
desti.write(data, 0, count);
}
}
}
}
}
catch (IOException e)
{
LOG.fatal(e);
result=false;
}
return result;
}
/**
* Cette methode renvoie la liste des fichiers contenus
* dans l'archive
*
* @return la liste des fichiers de l'archive
*/
public List listerLesFichiers()
{
final List result = new ArrayList<>();
try (
final FileInputStream fis = new FileInputStream(fichier);
final BufferedInputStream buffi = new BufferedInputStream(fis);
final ZipInputStream zis = new ZipInputStream(buffi);)
{
//extraction
ZipEntry entry = null;
// parcours des entrees de l'archive
while (null != (entry = zis.getNextEntry()))
{
result.add(entry.getName());
}
}
catch (IOException e)
{
LOG.fatal(e);
}
return result;
}
/**
* Cette methode prepare une nouvelle archive. Elle recupere les fichiers existants
*
* @return true si ok et false dans les autres cas
* @throws IOException
*/
private boolean preparerArchive() throws IOException
{
//initialisation du repertoire
String chemin = StringUtils.left(fichier.getAbsolutePath(), fichier.getAbsolutePath().lastIndexOf('\\'));
File repTemp = new File(chemin);
if (!repTemp.exists())
{
LOG.trace(repTemp.mkdirs());
}
boolean result = true;
//Extraction de l'ancienne archive si necessaire
final boolean archiveExistante = fichier.exists();
if (archiveExistante)
{
result &= new File(chemin + "/save").mkdirs();
FileUtils.copyFileToDirectory(fichier, new File(chemin + "/save/"));
final ZipUtil zipUtil = new ZipUtil(chemin + "/save/" + fichier.getName());
result &= zipUtil.extraireLesFichiers(new File(chemin + EXTRACTION_PATH));
}
//Preparation de la nouvelle archive
dest = new FileOutputStream(fichier);
checksum = new CheckedOutputStream(dest, new Adler32());
buff = new BufferedOutputStream(checksum);
out = new ZipOutputStream(buff);
out.setMethod(ZipOutputStream.DEFLATED);
out.setLevel(Deflater.BEST_COMPRESSION);
//Reimport des anciens fichiers
if (archiveExistante)
{
try
{
ajouterFichier(out, new File(chemin + EXTRACTION_PATH), "");
FileUtils.forceDelete(new File(chemin + EXTRACTION_PATH));
FileUtils.forceDelete(new File(chemin + "/save"));
}
catch (Exception e)
{
LOG.fatal(e);
result=false;
}
}
return result;
}
/**
* Cette methode est utilise pour ajouter recursivement
* les fichiers d'un repertoire.
*
* @param zipOutput
* @param fichiersOuRepertoire
* @param racine
*/
private void ajouterFichier(ZipOutputStream zipOutput, File fichiersOuRepertoire, String racine)
{
if (fichiersOuRepertoire==null)
{
return;
}
final byte[] data = new byte[BUFFER]; // $codepro.audit.disable unusedAssignment
if (fichiersOuRepertoire.isDirectory())
{
if (fichiersOuRepertoire.listFiles()!=null)
{
for (File tmp : Arrays.asList(fichiersOuRepertoire.listFiles()))
{
if ("extraction".equals(fichiersOuRepertoire.getName()))
{
ajouterFichier(zipOutput, tmp, racine + PATH_SEPARATOR);
}
else
{
ajouterFichier(zipOutput, tmp, racine + fichiersOuRepertoire.getName() + PATH_SEPARATOR);
}
}
}
}
else
{
try(
FileInputStream fi = new FileInputStream(fichiersOuRepertoire);
BufferedInputStream buffi = new BufferedInputStream(fi, BUFFER);
)
{
if (racine.startsWith(PATH_SEPARATOR))
{
racine = racine.substring(1,racine.length());
}
ZipEntry entry = new ZipEntry(racine + fichiersOuRepertoire.getName());
// ajout de cette entree dans le flux d'ecriture de l'archive ZIP
zipOutput.putNextEntry(entry);
int count=0;
while ((count = buffi.read(data, 0, BUFFER)) != -1)
{
zipOutput.write(data, 0, count);
}
zipOutput.closeEntry();
}
catch (IOException e)
{
LOG.error(e);
}
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy