All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.nuiton.util.FileUtil Maven / Gradle / Ivy

There is a newer version: 3.1
Show newest version
/*
 * #%L
 * Nuiton Utils
 * %%
 * Copyright (C) 2004 - 2010 CodeLutin
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as 
 * published by the Free Software Foundation, either version 3 of the 
 * License, or (at your option) any later version.
 * 
 * This program 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 Lesser Public License for more details.
 * 
 * You should have received a copy of the GNU General Lesser Public 
 * License along with this program.  If not, see
 * .
 * #L%
 */

package org.nuiton.util;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.SystemUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.swing.JFileChooser;
import java.awt.Component;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.nio.CharBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Opérations sur des fichiers. Copie, suppression, renommage,
 * recherche, fichiers d'un répertoire, sous-répertoires d'un répertoire,
 * récupération du basename ou de l'extension, création d'un fichier
 * temporaire, comparaison de dates de création, récupération d'une chaîne,
 * d'un Reader ou d'un Writer à partir d'un fichier, récupération du fichier
 * saisi dans une boîte de dialogue, conversions en byte[], en Stream...
 * 

* Created: 22 novembre 2004 * * @author Benjamin Poussin - [email protected] * @author Tony Chemit - [email protected] */ public class FileUtil { // FileUtil /** * Logger. */ private static final Log log = LogFactory.getLog(FileUtil.class); /** * Encoding utilisé (peut être redéfini) */ // TODO fdesbois 2011-04-16 : Perhaps change ISO encoding by UTF-8 public static String ENCODING = "ISO-8859-1"; /** * @deprecated since 2.6.13, prefer use same method in * jaxx.runtime.FileChooserUtil class in jaxx-runtime project * (see http://svn.nuiton.org/svn/jaxx/trunk/jaxx-runtime/src/main/java/jaxx/runtime/FileChooserUtil} */ @Deprecated protected static File currentDirectory = new File("."); /** * @param dir FIXME * @deprecated since 2.6.13, prefer use same method in * jaxx.runtime.FileChooserUtil class in jaxx-runtime project * (see http://svn.nuiton.org/svn/jaxx/trunk/jaxx-runtime/src/main/java/jaxx/runtime/FileChooserUtil} */ @Deprecated public static void setCurrentDirectory(File dir) { currentDirectory = dir; } /** * @return FIXME * @deprecated since 2.6.13, prefer use same method in * jaxx.runtime.FileChooserUtil class in jaxx-runtime project * (see http://svn.nuiton.org/svn/jaxx/trunk/jaxx-runtime/src/main/java/jaxx/runtime/FileChooserUtil} */ @Deprecated public static File getCurrentDirectory() { return currentDirectory; } /** * @deprecated since 2.6.13, prefer use same method in * jaxx.runtime.FileChooserUtil class in jaxx-runtime project * (see http://svn.nuiton.org/svn/jaxx/trunk/jaxx-runtime/src/main/java/jaxx/runtime/FileChooserUtil} */ @Deprecated public static class PatternChooserFilter extends javax.swing.filechooser.FileFilter { protected String pattern; protected String description; public PatternChooserFilter(String pattern, String description) { this.pattern = pattern; this.description = description; } @Override public boolean accept(File f) { return f.isDirectory() || f.getAbsolutePath().matches(pattern); } @Override public String getDescription() { return description; } } /** * Retourne le nom du fichier entre dans la boite de dialogue. * Si le bouton annuler est utilisé, ou qu'il y a une erreur retourne null. * * @param patternOrDescriptionFilters les filtres a utiliser, les chaines doivent etre données * par deux, le pattern du filtre + la description du filtre * @return le fichier accepté, ou null si rien n'est chois ou l'utilisateur a annulé * @see #getFile(javax.swing.filechooser.FileFilter...) * @deprecated since 2.6.13, prefer use same method in * jaxx.runtime.FileChooserUtil class in jaxx-runtime project * (see http://svn.nuiton.org/svn/jaxx/trunk/jaxx-runtime/src/main/java/jaxx/runtime/FileChooserUtil} */ @Deprecated public static File getFile(String... patternOrDescriptionFilters) { File result; result = getFile(null, patternOrDescriptionFilters); return result; } /** * Retourne le nom du fichier entre dans la boite de dialogue. * Si le bouton annuler est utilisé, ou qu'il y a une erreur retourne null. * * @param filters les filtres a ajouter * @return le fichier accepté, ou null si rien n'est chois ou l'utilisateur a annulé * @deprecated since 2.6.13, prefer use same method in * jaxx.runtime.FileChooserUtil class in jaxx-runtime project * (see http://svn.nuiton.org/svn/jaxx/trunk/jaxx-runtime/src/main/java/jaxx/runtime/FileChooserUtil} */ @Deprecated public static File getFile(javax.swing.filechooser.FileFilter... filters) { File result = getFile(null, filters); return result; } /** * Retourne le nom du fichier entre dans la boite de dialogue. * Si le bouton annuler est utilisé, ou qu'il y a une erreur retourne null. * * @param parent le component parent du dialog * @param patternOrDescriptionFilters les filtres a utiliser, les chaines doivent etre données * par deux, le pattern du filtre + la description du filtre * @return le fichier accepté, ou null si rien n'est chois ou l'utilisateur a annulé * @see #getFile(javax.swing.filechooser.FileFilter...) * @deprecated since 2.6.13, prefer use same method in * jaxx.runtime.FileChooserUtil class in jaxx-runtime project * (see http://svn.nuiton.org/svn/jaxx/trunk/jaxx-runtime/src/main/java/jaxx/runtime/FileChooserUtil} */ @Deprecated public static File getFile(Component parent, String... patternOrDescriptionFilters) { File result; result = getFile("Ok", "Ok", parent, patternOrDescriptionFilters); return result; } /** * Retourne le nom du fichier entre dans la boite de dialogue. * Si le bouton annuler est utilisé, ou qu'il y a une erreur retourne null. * * @param title le titre de la boite de dialogue * @param approvalText le label du boutton d'acceptation * @param parent le component parent du dialog * @param patternOrDescriptionFilters les filtres a utiliser, les chaines doivent etre données * par deux, le pattern du filtre + la description du filtre * @return le fichier accepté, ou null si rien n'est chois ou l'utilisateur a annulé * @see #getFile(javax.swing.filechooser.FileFilter...) * @deprecated since 2.6.13, prefer use same method in * jaxx.runtime.FileChooserUtil class in jaxx-runtime project * (see http://svn.nuiton.org/svn/jaxx/trunk/jaxx-runtime/src/main/java/jaxx/runtime/FileChooserUtil} */ @Deprecated public static File getFile(String title, String approvalText, Component parent, String... patternOrDescriptionFilters) { if (patternOrDescriptionFilters.length % 2 != 0) { throw new IllegalArgumentException( "Arguments must be (pattern, description) couple"); } javax.swing.filechooser.FileFilter[] filters = new javax.swing.filechooser.FileFilter[ patternOrDescriptionFilters.length / 2]; for (int i = 0; i < filters.length; i++) { String pattern = patternOrDescriptionFilters[i * 2]; String description = patternOrDescriptionFilters[i * 2 + 1]; filters[i] = new PatternChooserFilter(pattern, description); } File result; result = getFile(title, approvalText, parent, filters); return result; } /** * Retourne le nom du fichier entre dans la boite de dialogue. * Si le bouton annuler est utilisé, ou qu'il y a une erreur retourne null. * * @param parent le component parent du dialog * @param filters les filtres a ajouter * @return le fichier accepté, ou null si rien n'est chois ou l'utilisateur a annulé * @deprecated since 2.6.13, prefer use same method in * jaxx.runtime.FileChooserUtil class in jaxx-runtime project * (see http://svn.nuiton.org/svn/jaxx/trunk/jaxx-runtime/src/main/java/jaxx/runtime/FileChooserUtil} */ @Deprecated public static File getFile(Component parent, javax.swing.filechooser.FileFilter... filters) { File result = getFile("Ok", "Ok", parent, filters); return result; } /** * Retourne le nom du fichier entre dans la boite de dialogue. * Si le bouton annuler est utilisé, ou qu'il y a une erreur retourne null. * * @param title le titre de la boite de dialogue * @param approvalText le label du boutton d'acceptation * @param parent le component parent du dialog * @param filters les filtres a ajouter * @return le fichier accepté, ou null si rien n'est chois ou l'utilisateur a annulé * @deprecated since 2.6.13, prefer use same method in * jaxx.runtime.FileChooserUtil class in jaxx-runtime project * (see http://svn.nuiton.org/svn/jaxx/trunk/jaxx-runtime/src/main/java/jaxx/runtime/FileChooserUtil} */ @Deprecated public static File getFile(String title, String approvalText, Component parent, javax.swing.filechooser.FileFilter... filters) { try { JFileChooser chooser = new JFileChooser(currentDirectory); chooser.setDialogType(JFileChooser.CUSTOM_DIALOG); if (filters.length > 0) { if (filters.length == 1) { chooser.setFileFilter(filters[0]); } else { for (javax.swing.filechooser.FileFilter filter : filters) { chooser.addChoosableFileFilter(filter); } } } chooser.setFileSelectionMode(JFileChooser.FILES_ONLY); chooser.setDialogTitle(title); int returnVal = chooser.showDialog(parent, approvalText); if (returnVal == JFileChooser.APPROVE_OPTION) { File theFile = chooser.getSelectedFile(); if (theFile != null) { currentDirectory = theFile; return theFile.getAbsoluteFile(); } } } catch (Exception eee) { log.warn("Erreur:", eee); } return null; } /** * @return le nom du repertoire entre dans la boite de dialogue. * Si le bouton annuler est utilisé, ou qu'il y a une erreur retourne * null. * @deprecated since 2.6.13, prefer use same method in * jaxx.runtime.FileChooserUtil class in jaxx-runtime project * (see http://svn.nuiton.org/svn/jaxx/trunk/jaxx-runtime/src/main/java/jaxx/runtime/FileChooserUtil} */ @Deprecated public static String getDirectory() { return getDirectory(null, "Ok", "Ok"); } /** * @param title le nom de la boite de dialogue * @param approvalText le texte de l'action d'acceptation du répertoire dans le file chooser * @return le nom du repertoire entre dans la boite de dialogue. * Si le bouton annuler est utilisé, ou qu'il y a une erreur retourne * null. * @deprecated since 2.6.13, prefer use same method in * jaxx.runtime.FileChooserUtil class in jaxx-runtime project * (see http://svn.nuiton.org/svn/jaxx/trunk/jaxx-runtime/src/main/java/jaxx/runtime/FileChooserUtil} */ @Deprecated public static String getDirectory(String title, String approvalText) { String result = getDirectory(null, title, approvalText); return result; } /** * @param parent le component parent du dialog * @param title le nom de la boite de dialogue * @param approvalText le texte de l'action d'acceptation du répertoire dans le file chooser * @return le nom du repertoire entre dans la boite de dialogue. * Si le bouton annuler est utilisé, ou qu'il y a une erreur retourne * null. * @deprecated since 2.6.13, prefer use same method in * jaxx.runtime.FileChooserUtil class in jaxx-runtime project * (see http://svn.nuiton.org/svn/jaxx/trunk/jaxx-runtime/src/main/java/jaxx/runtime/FileChooserUtil} */ @Deprecated public static String getDirectory(Component parent, String title, String approvalText) { try { JFileChooser chooser = new JFileChooser(currentDirectory); chooser.setDialogType(JFileChooser.CUSTOM_DIALOG); chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); chooser.setDialogTitle(title); int returnVal = chooser.showDialog(parent, approvalText); if (returnVal == JFileChooser.APPROVE_OPTION) { File theFile = chooser.getSelectedFile(); if (theFile != null) { currentDirectory = theFile; if (theFile.isDirectory()) { return theFile.getAbsolutePath(); } } } else { return null; } } catch (Exception eee) { log.warn("Erreur:", eee); } return null; } /** * Permet de convertir des bytes en fichier, le fichier sera automatiquement * supprimé a la fin de la JVM. * * @param bytes the array of bytes to copy in dstination file * @return le fichier temporaire contenant les bytes * @throws IOException if any io pb */ public static File byteToFile(byte[] bytes) throws IOException { File file = File.createTempFile("FileUtil-byteToFile", ".tmp"); byteToFile(bytes, file); return file; } /** * Permet de convertir des bytes en fichier * * @param bytes the array of bytes to put in the given destination file * @param file le fichier dans lequel il faut ecrire les bytes * @return le fichier passé en parametre * @throws IOException if any io pb * @deprecated since 2.4.6, prefer use method {@link FileUtils#writeByteArrayToFile(File, byte[])} */ @Deprecated public static File byteToFile(byte[] bytes, File file) throws IOException { OutputStream out = new BufferedOutputStream(new FileOutputStream(file)); try { out.write(bytes); } finally { out.close(); } return file; } /** * Retourne un Reader utilisant l'encoding par defaut {@link #ENCODING}. * * @param file the given reader * @return the reader on the given file * @throws IOException if any io pb */ public static BufferedReader getReader(File file) throws IOException { return getReader(file, ENCODING); } /** * Retourne un reader utilisant l'encoding choisi et placé dans un * BufferedReader * * @param file the given file * @param encoding (ISO-8859-1, UTF-8, ...) * @return the buffered reader in the given encoding * @throws IOException if any io pb */ public static BufferedReader getReader(File file, String encoding) throws IOException { FileInputStream inf = new FileInputStream(file); InputStreamReader in = new InputStreamReader(inf, encoding); BufferedReader result = new BufferedReader(in); return result; } /** * Retourne un Writer utilisant l'encoding par defaut {@link #ENCODING}. * * @param file the given file * @return the writer on the given file * @throws IOException if any io pb */ public static BufferedWriter getWriter(File file) throws IOException { return getWriter(file, ENCODING); } /** * Retourne un writer utilisant l'encoding choisi et placé dans un * BufferedWriter * * @param file the given file * @param encoding (ISO-8859-1, UTF-8, ...) * @return the buffered writer on the given file with given encoding * @throws IOException if any io pb */ public static BufferedWriter getWriter(File file, String encoding) throws IOException { FileOutputStream outf = new FileOutputStream(file); OutputStreamWriter out = new OutputStreamWriter(outf, encoding); BufferedWriter result = new BufferedWriter(out); return result; } /** * Permet de creer un nouveu repertoire temporaire, l'effacement du * répertoire est a la charge de l'appelant * * @param prefix le prefix du fichier * @param suffix le suffix du fichier * @param tmpdir le répertoire temporaire ou il faut creer le repertoire * si null on utilise java.io.tmpdir * @return le fichier pointant sur le nouveau repertoire * @throws IOException if any io pb */ public static File createTempDirectory(String prefix, String suffix, File tmpdir) throws IOException { if (tmpdir == null) { tmpdir = new File(System.getProperty("java.io.tmpdir")); } File result = new File(tmpdir, prefix + System.currentTimeMillis() + suffix); while (result.exists()) { result = new File(tmpdir, prefix + System.currentTimeMillis() + suffix); } if (!result.mkdirs()) { throw new IOException("Can't create temporary directory: " + result); } return result; } /** * Permet de creer un nouveu repertoire temporaire, l'effacement du * répertoire est a la charge de l'appelant * * @param prefix le prefix du repertoire a creer * @param suffix le suffix du repertoire a creer. * @return the temprary created file * @throws IOException if any io pb */ public static File createTempDirectory(String prefix, String suffix) throws IOException { return createTempDirectory(prefix, suffix, null); } /** * Permet de sauver une chaine directement dans un fichier * * @param file Le fichier dans lequel il faut ecrire la chaine * @param content Le texte a ecrire dans le fichier * @param encoding encoding to use * @throws IOException if any pb while writing * @deprecated since 2.4.6, prefer use method {@link FileUtils#writeStringToFile(File, String, String)}. */ @Deprecated public static void writeString(File file, String content, String encoding) throws IOException { //fixme on doit tester le retour de la méthode, car il se peut que le répertoire // ne puisse être crée. File parentFile = file.getParentFile(); //TODO tchemit 2011-05-15 Must test if directory was created (use // the #createDirectoryIfNecessary method). if (parentFile != null) { parentFile.mkdirs(); } BufferedWriter out = getWriter(file, encoding); out.write(content); out.close(); } /** * Permet de donner une representation fichier pour une chaine de caractere. * Le fichier sera automatiquement effacé à la fin de la JVM. * * @param content le contenu du fichier temporaire * @return le fichier qui contient content * @throws IOException if any io pb */ public static File getTempFile(String content) throws IOException { return getTempFile(content, ""); } /** * Permet de donner une representation fichier pour une chaine de caractere. * Le fichier sera automatiquement effacé à la fin de la JVM. * * @param content le contenu du fichier temporaire * @param fileSuffix l'extension du fichier créé * @return le fichier qui contient content * @throws IOException if any io pb */ public static File getTempFile(String content, String fileSuffix) throws IOException { File result = File.createTempFile("tmp-" + FileUtil.class.getName(), fileSuffix); result.deleteOnExit(); FileUtils.write(result, content); return result; } /** * Equivalent de la methode basename unix. * basename("/tmp/toto.xml", ".xml") → "toto" * * @param file le fichier dont on souhaite le nom sans le chemin * @param suffixes si present represente le suffixe a eliminer du fichier * s'il est trouvé * @return le nom du fichier sans le suffixe si trouvé. */ public static String basename(File file, String... suffixes) { String result = basename(file.getName(), suffixes); return result; } /** * Equivalent de la methode basename unix. * basename("/tmp/toto.xml", ".xml") → "toto" * * @param name le nom du fichier dont on souhaite le nom sans le chemin * @param suffixes si present represente le suffixe a eliminer du fichier * s'il est trouvé * @return le nom du fichier sans le suffixe si trouvé. * @since 1.4.2 */ public static String basename(String name, String... suffixes) { String result = name; for (String suffixe : suffixes) { if (result.endsWith(suffixe)) { result = result.substring(0, result.length() - suffixe.length()); break; } } return result; } /** * Permet de récupérer l'extension d'un fichier * * @param file le fichier dont on souhaite l'extension * @param extchars la liste des caracteres pouvant former l'extension * dans l'ordre de preference. Si vide on utilise ".". * @return l'extension ou la chaine vide si le fichier n'a pas d'extension * l'extension ne contient pas le chaine de delimitation */ public static String extension(File file, String... extchars) { String name = file.getName(); String result = extension(name, extchars); return result; } /** * Permet de récupérer l'extension d'un nom de fichier * * @param name le nom du fichier dont on souhaite l'extension * @param extchars la liste des caracteres pouvant former l'extension * dans l'ordre de preference. Si vide on utilise ".". * @return l'extension ou la chaine vide si le fichier n'a pas d'extension * l'extension ne contient pas le chaine de delimitation * @since 1.4.2 */ public static String extension(String name, String... extchars) { String result = ""; if (extchars.length == 0) { extchars = new String[]{"."}; } for (String extchar : extchars) { int pos = name.lastIndexOf(extchar); if (pos != -1) { result = name.substring(pos + extchar.length()); break; } } return result; } /** * Recupère le fichier dans le même répertoire que le fichier donné et dont * on a changé l'extension. * * @param file le fichier d'origine * @param newExtension la nouvelle extension à utiliser * @param extchars la liste des extensions possibles * @return le fichier dont on a changé l'extension * @throws IOException si aucune extension trouvé dans le fichier d'origine * @since 1.4.2 */ public static File changeExtension(File file, String newExtension, String... extchars) throws IOException { String name = file.getName(); String newName = changeExtension(name, newExtension, extchars); File newFile = new File(file.getParentFile(), newName); return newFile; } /** * Change l'extension du fichier en entrée avec la nouvelle extension * * @param name le nom de fichier à transformer * @param newExtension la nouvelle extension à utiliser * @param extchars la liste des extensions possibles * @return le nouveau nom de fichier * @throws IOException si aucune extension trouvé dans le fichier d'origine * @since 1.4.2 */ public static String changeExtension(String name, String newExtension, String... extchars) throws IOException { String extension = extension(name, extchars); if (extension == null) { throw new IOException("Could not find extension for name " + name + " within " + Arrays.toString(extchars)); } String nameWithoutExtension = name.substring( 0, name.length() - extension.length()); String newName = nameWithoutExtension + newExtension; return newName; } /** * Recupère le fichier mirroir du fichier {@code file} donnée qui est dans * l'arborescence de {@code inputDirectory} dans le répertoire * {@code ouputDirectory}. * * @param inputDirectory le répertoire de départ * @param outputDirectory le répertoire cible * @param file le fichier * @return le fichier mirroir dans le répertoire cible * @since 1.4.2 */ public static File getRelativeFile(File inputDirectory, File outputDirectory, File file) { String inputPath = inputDirectory.getAbsolutePath(); String s = file.getAbsolutePath(); int index = s.indexOf(inputPath); if (index == -1) { throw new IllegalArgumentException( "File " + file + " is not in " + inputDirectory); } String relativePath = s.substring(inputPath.length()); File result = new File(outputDirectory, relativePath); return result; } public interface FileAction { boolean doAction(File f); } /** * Retourne tous les sous répertoires du répertoire passé en argument. * * @param directory un répertoire * @return une liste d'objet {@link File} de répertoires et ceci * recursivement à partir de directory, si directory * n'est pas un répertoire la liste est vide. */ public static List getSubDirectories(File directory) { class DirectoryFilter implements FileFilter { @Override public boolean accept(File f) { return f.isDirectory(); } } return getFilteredElements(directory, new DirectoryFilter(), true); } /** * Retourne tous les fichiers du répertoire passé en argument. * * @param directory un répertoire * @return une liste d'objet {@link File} des fichiers et ceci * recursivement à partir de directory, si directory n'est pas un * répertoire la liste est vide */ public static List getFiles(File directory) { class NormalFileFilter implements FileFilter { @Override public boolean accept(File f) { return f.isFile(); } } return getFilteredElements(directory, new NormalFileFilter(), true); } /** * Retourne les fichiers d'un répertoire qui satisfont un certain pattern. * La recherche est faite récursivement dans les sous répertoires * * @param directory le répertoire à partir duquel il faut faire la recherche * @param pattern le pattern que doit respecter le fichier pour être dans la * liste résultante * @param recursively flag pour indiquer si on doit descendre dans les sous répertoires * @return une liste d'objet {@link File} qui ont s'attisfait le * pattern. */ public static List find(File directory, final String pattern, boolean recursively) { final String root = directory.getAbsolutePath(); final int rootLength = root.length(); return getFilteredElements(directory, new FileFilter() { @Override public boolean accept(File f) { String longFilename = f.getAbsolutePath(); // + 1 to remove the first / or \ String filename = longFilename.substring(rootLength + 1); return filename.matches(pattern); } }, recursively); } /** * Retourne la liste de toutes les fichiers ou répertoire qui s'attisfont * le filtre * * @param directory repertoire à partir duquel il faut faire la recherche * @param ff le filtre à appliquer pour savoir si le fichier parcouru doit * être conservé dans les résultats, ou null pour tous les fichiers * @param recursively un flag pour indiquer si on doit descendre dans les répertoires * @return une liste d'objet {@link File}, qui s'attisfont le filtre */ public static List getFilteredElements(File directory, FileFilter ff, boolean recursively) { ArrayList result = new ArrayList(); LinkedList todo = new LinkedList(); if (directory.isDirectory()) { todo.addAll(Arrays.asList(directory.listFiles())); } while (todo.size() > 0) { File file = todo.removeFirst(); if (recursively && file.isDirectory()) { File[] childs = file.listFiles(); if (childs != null) { // null if we don't have access to directory todo.addAll(Arrays.asList(childs)); } } if (ff == null || ff.accept(file)) { result.add(file); } } return result; } /** * Permet de faire une action avant le parcours des fichiers, c-a-d que * l'on fera l'action sur les fichiers contenu dans un répertoire * après l'action sur le répertoire lui même. * * @param f le fichier ou répertoire à partir duquel il faut commencer * @param fileAction l'action à effectuer sur chaque fichier * @return le résultat des fileAction executé sur les fichiers, chaque * résultat de FileAction sont assemblé par un ET logique pour donner * le résultat final */ public static boolean walkAfter(File f, FileAction fileAction) { boolean result = fileAction.doAction(f); if (f.isDirectory()) { File list[] = f.listFiles(); for (File aList : list) { result = result && walkAfter(aList, fileAction); } } return result; } /** * Permet de faire une action apès le parcours des fichiers, c-a-d que * l'on fera l'action sur les fichiers contenu dans un répertoire * avant l'action sur le répertoire lui même. * * @param f le fichier ou répertoire à partir duquel il faut commencer * @param fileAction l'action à effectuer sur chaque fichier * @return le résultat des fileAction executé sur les fichiers, chaque * résultat de FileAction sont assemblé par un ET logique pour donner * le résultat final */ public static boolean walkBefore(File f, FileAction fileAction) { boolean result = true; if (f.isDirectory()) { File list[] = f.listFiles(); for (File aList : list) { result = result && walkBefore(aList, fileAction); } } return result && fileAction.doAction(f); } /** * Copie recursivement le repertoire source dans le repertoire destination *

* copyRecursively("/truc/titi", "/var/tmp") donnera le repertoire * "/var/tmp/titi" * * @param srcDir le répertoire source à copier * @param destDir le répertoire destination où copier * @param includePatterns les patterns que doivent resperter les * fichiers/repertoires pour etre copié. Si vide alors tout est copié * @throws IOException if any io pb */ public static void copyRecursively(File srcDir, File destDir, String... includePatterns) throws IOException { copyAndRenameRecursively(srcDir, destDir, null, null, includePatterns); } /** * Copie recursivement le repertoire source dans le repertoire destination *

* copyRecursively("/truc/titi", "/var/tmp", "bidulle") donnera le repertoire * "/var/tmp/bidulle", 'bidulle' remplacant 'titi' * * @param srcDir le répertoire source à copier * @param destDir le répertoire destination où copier * @param renameFrom pattern to permit rename file before uncompress it * @param renameTo new name for file if renameFrom is applicable to it * you can use $1, $2, ... if you have '(' ')' in renameFrom * @param includePatterns les patterns que doivent resperter les * fichiers/repertoires pour etre copié. Si vide alors tout est copié * @throws IOException if any io pb */ public static void copyAndRenameRecursively(File srcDir, File destDir, String renameFrom, String renameTo, String... includePatterns) throws IOException { copyAndRenameRecursively(srcDir, destDir, true, renameFrom, renameTo, false, includePatterns ); } /** * Copie recursivement le repertoire source dans le repertoire destination *

* copyRecursively("/truc/titi", "/var/tmp", "bidulle") donnera le repertoire * "/var/tmp/bidulle", 'bidulle' remplacant 'titi' * * @param srcDir le répertoire source à copier * @param destDir le répertoire destination où copier * @param includeSrcDir si vrai alors le repertoire source est copie dans le * repertoire destination et non pas seulement les fichiers qu'il contient * @param renameFrom pattern to permit rename file before uncompress it * @param renameTo new name for file if renameFrom is applicable to it * you can use $1, $2, ... if you have '(' ')' in renameFrom * @param exclude inverse include pattern interpretation * @param includePatterns les patterns que doivent resperter les * fichiers/repertoires pour etre copié. Si vide alors tout est copié * @throws IOException if any io pb */ public static void copyAndRenameRecursively(File srcDir, File destDir, boolean includeSrcDir, String renameFrom, String renameTo, boolean exclude, String... includePatterns) throws IOException { String rootSrc; if (includeSrcDir) { rootSrc = srcDir.getParent(); } else { rootSrc = srcDir.getPath(); } List files = getFilteredElements(srcDir, null, true); log.debug("copyRecursively: " + files); for (File file : files) { boolean doCopy = copyRecursivelyAccept(file, includePatterns); if (exclude ^ doCopy) { String path = file.getPath().substring(rootSrc.length()); if (renameFrom != null && renameTo != null) { String tmp = path.replaceAll(renameFrom, renameTo); if (log.isDebugEnabled()) { log.debug("rename " + path + " → " + tmp); } path = tmp; } File destFile = new File(destDir, path); if (file.isDirectory()) { log.debug("create directory: " + destFile); //fixme on doit tester le retour de la méthode, car il se peut que le répertoire // ne puisse être copié. createDirectoryIfNecessary(destFile); } else { log.debug("copy " + path + " to " + destFile); FileUtils.copyFile(file, destFile); } } } } /** * Get a ByteArrayOutputStream containing all data that could be read from the given InputStream * * @param inputStream the stream to read * @param defaultBufferSize the buffer size * @return the input stream read for input * @throws IOException if any pb while reading or writing */ public static ByteArrayOutputStream readBytesFrom(InputStream inputStream, int defaultBufferSize) throws IOException { ByteArrayOutputStream outputStream = new ByteArrayOutputStream( defaultBufferSize); byte[] buffer = new byte[defaultBufferSize]; int readBytes = inputStream.read(buffer); while (readBytes > 0) { outputStream.write(buffer, 0, readBytes); readBytes = inputStream.read(buffer); } return outputStream; } /** * @param file le fichier à tester. * @param includePatterns les patterns pour accepeter le fichier depuis son nom * @return {@code true} si le fichier est accepté, false> autrement. */ private static boolean copyRecursivelyAccept(File file, String[] includePatterns) { boolean result = includePatterns.length == 0; String filename = file.getAbsolutePath(); for (String pattern : includePatterns) { result = filename.matches(pattern); if (result) { break; } } return result; } /** * Use the linePattern to break the given CharBuffer into lines, applying * the input pattern to each line to see if we have a match *

* Code taken from : *

* http://java.sun.com/javase/6/docs/technotes/guides/io/example/Grep.java * * @param regex regex to search into file * @param cb nio buffer * @return matching lines (or {code null} if no matching lines) * @since 1.1.2 */ protected static List grep(String regex, CharBuffer cb) { List linesList = null; Pattern pattern = Pattern.compile(regex); Pattern linePattern = Pattern.compile(".*\r?\n"); Matcher lm = linePattern.matcher(cb); // Line matcher Matcher pm = null; // Pattern matcher //int lines = 0; while (lm.find()) { //lines++; CharSequence cs = lm.group(); // The current line if (pm == null) { pm = pattern.matcher(cs); } else { pm.reset(cs); } if (pm.find()) { // init if (linesList == null) { linesList = new ArrayList(); } linesList.add(cs); } if (lm.end() == cb.limit()) { break; } } return linesList; } /** * Java implementation for the unix grep command. *

* Code taken from : *

* http://java.sun.com/javase/6/docs/technotes/guides/io/example/Grep.java *

* May fail on windows with error : * The requested operation cannot be performed on a file with a user-mapped section open * * @param searchRegex regex to search into file * @param f file to search into * @param encoding encoding to use * @return matching lines (or {code null} if no matching lines) * @throws IOException FIXME * @since 1.1.2 */ public static List grep(String searchRegex, File f, String encoding) throws IOException { List lines = null; FileInputStream fis = null; FileChannel fc = null; try { // Open the file and then get a channel from the stream fis = new FileInputStream(f); fc = fis.getChannel(); // Get the file's size and then map it into memory int sz = (int) fc.size(); MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, sz); // Decode the file into a char buffer Charset charset = Charset.forName(encoding); CharsetDecoder decoder = charset.newDecoder(); CharBuffer cb = decoder.decode(bb); // Perform the search lines = grep(searchRegex, cb); } finally { // Close the channel and the stream if (fc != null) { fc.close(); } if (fis != null) { fis.close(); } } return lines; } /** * Java implementation for the unix grep command. *

* May fail on windows with error : * The requested operation cannot be performed on a file with a user-mapped section open * * @param searchRegex regex to search into file * @param rootDirectory directory to seacrh into * @param fileRegex regex for file to find in {@code rootDirectory} * @param encoding encoding to use * @return all matching lines for each files * @throws IOException FIXME * @since 1.1.2 */ public static Map> grep(String searchRegex, File rootDirectory, String fileRegex, String encoding) throws IOException { Map> results = new HashMap>(); List files = find(rootDirectory, fileRegex, true); for (File file : files) { List lines = grep(searchRegex, file, encoding); if (lines != null) { results.put(file, lines); } } return results; } /** * Search for files matching regex in current directory. *

* May fail on windows with error : * The requested operation cannot be performed on a file with a user-mapped section open * * @param searchRegex regex to search into file * @param fileRegex regex for file to find in current dir * @param encoding encoding to use * @return all matching lines for each files * @throws IOException FIXME * @since 1.1.2 */ public static Map> grep(String searchRegex, String fileRegex, String encoding) throws IOException { Map> results = grep(searchRegex, new File("."), fileRegex, encoding); return results; } /** * Sed implementation for a single file. *

* Oginal source code from http://kickjava.com/src/org/apache/lenya/util/SED.java.htm. *

* May fail on windows with error : * The requested operation cannot be performed on a file with a user-mapped section open * * @param searchRegex Prefix which shall be replaced * @param replace Prefix which is going to replace the original * @param file File which sed shall be applied * @param encoding charset encoding * @throws IOException FIXME * @since 1.1.2 */ public static void sed(String searchRegex, String replace, File file, String encoding) throws IOException { Pattern pattern = Pattern.compile(searchRegex); String outString = null; FileInputStream fis = new FileInputStream(file); try { // Open the file and then get a channel from the stream FileChannel fc = fis.getChannel(); // Get the file's size and then map it into memory int sz = (int) fc.size(); MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, sz); // Decode the file into a char buffer // Charset and decoder for encoding Charset charset = Charset.forName(encoding); CharsetDecoder decoder = charset.newDecoder(); CharBuffer cb = decoder.decode(bb); Matcher matcher = pattern.matcher(cb); outString = matcher.replaceAll(replace); } finally { fis.close(); } if (outString != null) { PrintStream ps = new PrintStream(new FileOutputStream(file)); try { ps.print(outString); } finally { ps.close(); } } } /** * Java implementation for the unix sed command. *

* May fail on windows with error : * The requested operation cannot be performed on a file with a user-mapped section open * * @param searchRegex regex to search into file * @param replace string to replace matching patterns * @param rootDirectory directory to search into * @param fileRegex regex for file to find in {@code rootDirectory} * @param encoding encoding to use * @throws IOException FIXME * @since 1.1.2 */ public static void sed(String searchRegex, String replace, File rootDirectory, String fileRegex, String encoding) throws IOException { List files = find(rootDirectory, fileRegex, true); for (File file : files) { sed(searchRegex, replace, file, encoding); } } /** * Java implementation for the unix sed command. *

* May fail on windows with error : * The requested operation cannot be performed on a file with a user-mapped section open * * @param searchRegex regex to search into file * @param replace string to replace matching patterns * @param fileRegex regex for file to find in current dir * @param encoding encoding to use * @throws IOException FIXME * @since 1.1.2 */ public static void sed(String searchRegex, String replace, String fileRegex, String encoding) throws IOException { sed(searchRegex, replace, new File("."), fileRegex, encoding); } /** * Create the directory (and his parents) if necessary. * * @param dir the directory to create if not exisiting * @return {@code true} if directory was created, {@code false} if was no * need to create it * @since 1.3.2 */ public static boolean createDirectoryIfNecessary(File dir) { if (!dir.exists()) { // do not throw exception if directory was created by another thread return dir.mkdirs(); } return false; } /** * Obtain a file from the given {@code rootDirectory}, applying given paths. *

* For example with paths = a, b and c, then result is : *

     * root/a/b/c
     * 
* * @param rootDirectory the root directory * @param paths paths to apply * @return the final file * @since 2.2 */ public static File getFileFromPaths(File rootDirectory, String... paths) { File result = rootDirectory; for (String path : paths) { result = new File(result, path); } return result; } /** * Obtain a file fro the given {@code rootDirectory}, applying the fqn. *

* For example with fqn = a.b.c, the result is : *

     * root/a/b/c
     * 
* * @param rootDirectory the root directory * @param fqn fqn of searched file * @return the final file * @since 2.2 */ public static File getFileFromFQN(File rootDirectory, String fqn) { String[] paths = fqn.split("\\."); File result = getFileFromPaths(rootDirectory, paths); return result; } /** * Obtain a directory and creates it if required to place some test data. *

* The directory will be : *

     *     java.io.tmpdir/testclassName.fqn/methodName[/classifier]/timestamp
     * 
* * @param testClassName test class name * @param methodName method name * @param classifier optional classifier * @param timestamp timestamp * @return the computed and created if required directory. * @since 2.6.10 */ public static File getTestSpecificDirectory(Class testClassName, String methodName, String classifier, long timestamp) { File tempDirFile = SystemUtils.getJavaIoTmpDir(); // create the directory to store database data String dataBasePath = testClassName.getName() + File.separator // a directory with the test class name + methodName; // a sub-directory with the method name if (StringUtils.isNotBlank(classifier)) { dataBasePath += classifier; } dataBasePath += '_' + timestamp; // and a timestamp File databaseFile = new File(tempDirFile, dataBasePath); return databaseFile; } /** * Tests if a file is GZipped. * * @param file file to test * @return {@code true} if file is gzipped, {@code false} otherwise * @throws IOException if any io errors while reading file * @since 3.0 */ public static boolean isGzipFile(File file) throws IOException { InputStream in = new BufferedInputStream(new FileInputStream(file)); try { boolean gzip = GZUtil.isGzipStream(in); in.close(); return gzip; } finally { IOUtils.closeQuietly(in); } } } // FileUtil




© 2015 - 2025 Weber Informatics LLC | Privacy Policy