/* * Copyright 2010-2015 Institut Pasteur. * * This file is part of Icy. * * Icy 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. * * Icy 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 Icy. If not, see <http://www.gnu.org/licenses/>. */ package icy.file; import icy.network.NetworkUtil; import icy.system.IcyExceptionHandler; import icy.system.SystemUtil; import icy.system.thread.ThreadUtil; import icy.util.StringUtil; import java.io.BufferedReader; import java.io.File; import java.io.FileFilter; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.util.ArrayList; import java.util.List; /** * @author stephane */ public class FileUtil { public static final char separatorChar = '/'; public static final String separator = "/"; public static final String APPLICATION_DIRECTORY = getApplicationDirectory(); /** * Cleanup the file path (replace some problematic character by "_") */ public static String cleanPath(String filePath) { String result = filePath; if (result != null) { // remove ':' other than for drive separation if (result.length() >= 2) result = result.substring(0, 2) + result.substring(2).replaceAll(":", "_"); // remove '!' characters result = result.replaceAll("!", "_"); // remove '#' characters result = result.replaceAll("#", "_"); } return result; } /** * Transform any system specific path in java generic path form.<br> * Ex: "C:\windows" --> "C:/windows" */ public static String getGenericPath(String path) { if (path != null) return path.replace('\\', '/'); return null; } /** * Returns default temporary directory. * ex:<br> * <code>c:/temp</code><br> * <code>/tmp</code><br> * Same as {@link SystemUtil#getTempDirectory()} */ public static String getTempDirectory() { final String result = FileUtil.getGenericPath(SystemUtil.getProperty("java.io.tmpdir")); final int len = result.length(); // remove last separator if ((len > 1) && (result.charAt(len - 1) == FileUtil.separatorChar)) return result.substring(0, len - 1); return result; } /** * Change path extension.<br> * Ex : setExtension(path, ".dat")<br> * "c:\temp" --> "c:\temp.dat" * "c:\file.out" --> "c:\file.dat" * "" --> "" */ public static String setExtension(String path, String extension) { final String finalPath = getGenericPath(path); if (StringUtil.isEmpty(finalPath)) return ""; final int len = finalPath.length(); String result = finalPath; final int dotIndex = result.lastIndexOf("."); // ensure we are modifying an extension if (dotIndex >= 0 && (len - dotIndex) <= 5) { // we consider that an extension starting with a digit is not an extension if (((dotIndex + 1) == len) || !Character.isDigit(result.charAt(dotIndex + 1))) result = result.substring(0, dotIndex); } if (extension != null) result += extension; return result; } public static void ensureParentDirExist(String filename) { ensureParentDirExist(new File(getGenericPath(filename))); } public static boolean ensureParentDirExist(File file) { final String dir = file.getParent(); if (dir != null) return createDir(dir); return true; } public static boolean createDir(String dirname) { return createDir(new File(getGenericPath(dirname))); } public static boolean createDir(File dir) { if (!dir.exists()) return dir.mkdirs(); return true; } public static File createFile(String filename) { return createFile(new File(getGenericPath(filename))); } public static File createFile(File file) { if (!file.exists()) { // create parent directory if not exist ensureParentDirExist(file); try { file.createNewFile(); } catch (Exception e) { System.err.println("Error: can't create file '" + file.getAbsolutePath() + "':"); IcyExceptionHandler.showErrorMessage(e, false); return null; } } return file; } /** * Transform the specified list of path to file. */ public static File[] toFiles(String[] paths) { final File[] result = new File[paths.length]; for (int i = 0; i < paths.length; i++) result[i] = new File(paths[i]); return result; } /** * Transform the specified list of path to file. */ public static List<File> toFiles(List<String> paths) { final List<File> result = new ArrayList<File>(paths.size()); for (String path : paths) result.add(new File(path)); return result; } /** * Transform the specified list of file to path. */ public static String[] toPaths(File[] files) { final String[] result = new String[files.length]; for (int i = 0; i < files.length; i++) result[i] = getGenericPath(files[i].getAbsolutePath()); return result; } /** * Transform the specified list of file to path. */ public static List<String> toPaths(List<File> files) { final List<String> result = new ArrayList<String>(files.size()); for (File file : files) result.add(getGenericPath(file.getAbsolutePath())); return result; } /** * Create a symbolic link file */ public static boolean createLink(String path, String target) { final String finalPath = getGenericPath(path); ensureParentDirExist(finalPath); // use OS dependent command (FIXME : replace by java 7 API when available) if (SystemUtil.isLinkSupported()) { final Process process = SystemUtil.exec("ln -s " + target + " " + finalPath); // error while executing command if (process == null) return false; try { return (process.waitFor() == 0); } catch (InterruptedException e) { System.err.println("FileUtil.createLink(" + path + ", " + target + ") error :"); IcyExceptionHandler.showErrorMessage(e, false); return false; } } // use classic copy if link isn't supported by OS return copy(target, finalPath, true, false, false); } public static byte[] load(String path, boolean displayError) { return load(new File(getGenericPath(path)), displayError); } public static byte[] load(File file, boolean displayError) { return NetworkUtil.download(file, null, displayError); } public static boolean save(String path, byte[] data, boolean displayError) { return save(new File(getGenericPath(path)), data, displayError); } public static boolean save(File file, byte[] data, boolean displayError) { final File f = createFile(file); if (f != null) { try { final FileOutputStream out = new FileOutputStream(f); out.write(data, 0, data.length); out.close(); } catch (Exception e) { if (displayError) System.err.println(e.getMessage()); // delete incorrect file f.delete(); return false; } return true; } return false; } /** * Returns the path where the application is located (current directory).<br> * Ex: "D:/Apps/Icy" */ public static String getApplicationDirectory() { String result; try { // try to get from sources final File f = new File(FileUtil.class.getProtectionDomain().getCodeSource().getLocation().toURI()); // if already a folder, return it directly if (f.isDirectory()) result = f.getAbsolutePath(); else result = f.getParentFile().getAbsolutePath(); } catch (Exception e1) { try { // try to get from resource (this sometime return incorrect folder on mac osx) result = new File(ClassLoader.getSystemClassLoader().getResource(".").toURI()).getAbsolutePath(); } catch (Exception e2) { // use launch directory (which may be different from application directory) result = new File(System.getProperty("user.dir")).getAbsolutePath(); } } try { // so we replace any %20 sequence in space result = URLDecoder.decode(result, "UTF-8"); } catch (UnsupportedEncodingException e) { // ignore } return getGenericPath(result); } /** * @deprecated Use {@link #getApplicationDirectory()} instead. */ @Deprecated public static String getCurrentDirectory() { return getApplicationDirectory(); } /** * Return directory information from specified path<br> * <br> * getDirectory("/file.txt") --> "/"<br> * getDirectory("D:/temp/file.txt") --> "D:/temp/"<br> * getDirectory("D:/temp/") --> "D:/temp/"<br> * getDirectory("D:/temp") --> "D:/"<br> * getDirectory("C:file.txt") --> "C:"<br> * getDirectory("file.txt") --> ""<br> * getDirectory("file") --> ""<br> * getDirectory(null) --> "" */ public static String getDirectory(String path, boolean separator) { final String finalPath = getGenericPath(path); if (!StringUtil.isEmpty(finalPath)) { int index = finalPath.lastIndexOf(FileUtil.separatorChar); if (index != -1) return finalPath.substring(0, index + (separator ? 1 : 0)); index = finalPath.lastIndexOf(':'); if (index != -1) return finalPath.substring(0, index + 1); } return ""; } /** * Return directory information from specified path<br> * <br> * getDirectory("/file.txt") --> "/"<br> * getDirectory("D:/temp/file.txt") --> "D:/temp/"<br> * getDirectory("D:/temp/") --> "D:/temp/"<br> * getDirectory("D:/temp") --> "D:/"<br> * getDirectory("C:file.txt") --> "C:"<br> * getDirectory("file.txt") --> ""<br> * getDirectory("file") --> ""<br> * getDirectory(null) --> "" */ public static String getDirectory(String path) { return getDirectory(path, true); } /** * Return filename information from specified path.<br> * <br> * getFileName("/file.txt") --> "file.txt"<br> * getFileName("D:/temp/file.txt") --> "file.txt"<br> * getFileName("C:file.txt") --> "file.txt"<br> * getFileName("file.txt") --> "file.txt"<br> * getFileName(null) --> "" */ public static String getFileName(String path) { return getFileName(path, true); } /** * Return filename information from specified path.<br> * Filename's extension is returned depending the withExtension flag value<br> * <br> * getFileName("/file.txt") --> "file(.txt)"<br> * getFileName("D:/temp/file.txt") --> "file(.txt)"<br> * getFileName("C:file.txt") --> "file(.txt)"<br> * getFileName("file.txt") --> "file(.txt)"<br> * getFileName(null) --> "" */ public static String getFileName(String path, boolean withExtension) { final String finalPath = getGenericPath(path); if (StringUtil.isEmpty(finalPath)) return ""; int index = finalPath.lastIndexOf(FileUtil.separatorChar); final String fileName; if (index != -1) fileName = finalPath.substring(index + 1); else { index = finalPath.lastIndexOf(':'); if (index != -1) fileName = finalPath.substring(index + 1); else fileName = finalPath; } if (withExtension) return fileName; index = fileName.lastIndexOf('.'); if (index == 0) return ""; else if (index != -1) return fileName.substring(0, index); else return fileName; } /** * Return filename extension information from specified path<br> * Dot character is returned depending the withDot flag value<br> * <br> * getFileExtension("/file.txt") --> "(.)txt)"<br> * getFileExtension("D:/temp/file.txt.old") --> "(.)old"<br> * getFileExtension("C:/win/dir2/file") --> ""<br> * getFileExtension(".txt") --> "(.)txt)"<br> * getFileExtension(null) --> "" */ public static String getFileExtension(String path, boolean withDot) { final String finalPath = getGenericPath(path); if (StringUtil.isEmpty(finalPath)) return ""; final int indexSep = finalPath.lastIndexOf(separatorChar); final int indexDot = finalPath.lastIndexOf('.'); if (indexDot < indexSep) return ""; if (withDot) return finalPath.substring(indexDot); return finalPath.substring(indexDot + 1); } /** * Rename the specified <code>src</code> file to <code>dst</code> file. * Return false if the method failed. * * @param src * the source filename we want to rename from. * @param dst * the destination filename we want to rename to. * @param force * If set to <code>true</code> the destination file is overwritten if it was already * existing. * @see File#renameTo(File) */ public static boolean rename(String src, String dst, boolean force) { return rename(new File(getGenericPath(src)), new File(getGenericPath(dst)), force); } /** * @deprecated Use {@link #rename(String, String, boolean)} instead */ @Deprecated public static boolean rename(String src, String dst, boolean force, boolean wantHidden) { return rename(src, dst, force); } /** * Rename the specified 'src' file to 'dst' file. * Return false if the method failed. * * @see File#renameTo(File) */ public static boolean rename(File src, File dst, boolean force) { if (src.exists()) { if (dst.exists()) { if (force) { if (!delete(dst, true)) { System.err.println("Cannot rename '" + src.getAbsolutePath() + "' to '" + dst.getAbsolutePath() + "'"); System.err.println("Reason : destination cannot be overwritten."); System.err.println("Make sure it is not locked by another program (e.g. Eclipse)"); System.err.println("Also check that you have the rights to do this operation."); return false; } } else { System.err.println("Cannot rename '" + src.getAbsolutePath() + "' to '" + dst.getAbsolutePath() + "'"); System.err.println("The destination already exists."); System.err.println("Use the 'force' flag to force the operation."); return false; } } // create parent directory if not exist ensureParentDirExist(dst); // we can need that first to rename file if (!src.setWritable(true, false)) src.setWritable(true, true); final long start = System.currentTimeMillis(); // renameTo is not very reliable, better to do several try boolean done = src.renameTo(dst); while (!done && (System.currentTimeMillis() - start) < (10 * 1000)) { // try to release objects which maintain lock System.gc(); ThreadUtil.sleep(1000); // may help if (!src.setWritable(true, false)) src.setWritable(true, true); // retry done = src.renameTo(dst); } if (!done) { System.err.println("Cannot rename '" + src.getAbsolutePath() + "' to '" + dst.getAbsolutePath() + "'"); System.err.println("Check that the source file is not locked."); return false; } return true; } // missing input file System.err.println("Cannot rename '" + src.getAbsolutePath() + "' to '" + dst.getAbsolutePath() + "'"); System.err.println("Input file '" + src.getAbsolutePath() + "' not found !"); return false; } /** * @deprecated Use {@link #rename(File, File, boolean)} instead */ @Deprecated public static boolean rename(File src, File dst, boolean force, boolean wantHidden) { return rename(src, dst, force); } /** * @deprecated Use {@link #rename(String, String, boolean)} instead */ @Deprecated public static boolean move(String src, String dst, boolean force) { return rename(src, dst, force); } /** * @deprecated Use {@link #move(String, String, boolean)} instead */ @Deprecated public static boolean move(String src, String dst, boolean force, boolean wantHidden) { return move(src, dst, force); } /** * @deprecated Use {@link #rename(File, File, boolean)} instead */ @Deprecated public static boolean move(File src, File dst, boolean force) { return rename(src, dst, force); } /** * @deprecated Use {@link #move(File, File, boolean)} instead */ @Deprecated public static boolean move(File src, File dst, boolean force, boolean wantHidden) { return move(src, dst, force); } /** * Copy src to dst.<br> * Return true if file(s) successfully copied, false otherwise. * * @param src * source file or directory * @param dst * destination file or directory * @param force * force copy to previous existing file * @param recursive * also copy sub directory * @return boolean */ public static boolean copy(String src, String dst, boolean force, boolean recursive) { return copy(new File(getGenericPath(src)), new File(getGenericPath(dst)), force, recursive); } /** * @deprecated Use {@link #copy(String, String, boolean, boolean)} instead */ @Deprecated public static boolean copy(String src, String dst, boolean force, boolean wantHidden, boolean recursive) { return copy(src, dst, force, recursive); } /** * Copy src to dst with the specified parameters.<br> * Return true if the operation succeed considering the specified parameters.<br> * That means if you try to copy a hidden file with wantHidden set to false then true is * returned<br> * even if the file is not copied. * * @param src * source file or directory * @param dst * destination file or directory * @param force * force copy to previous existing file * @param recursive * also copy sub directory * @return boolean */ public static boolean copy(File src, File dst, boolean force, boolean recursive) { return copy_(src, dst, force, recursive, false); } /** * @deprecated Use {@link #copy(File, File, boolean, boolean)} instead */ @Deprecated public static boolean copy(File src, File dst, boolean force, boolean wantHidden, boolean recursive) { return copy(src, dst, force, recursive); } /** * internal copy */ private static boolean copy_(File src, File dst, boolean force, boolean recursive, boolean inRecurse) { // directory copy ? if (src.isDirectory()) { // no recursive copy --> end if (inRecurse && !recursive) return true; // so dst specify a directory too createDir(dst); boolean result = true; // get files list final String files[] = src.list(); // recursive copy for (int i = 0; i < files.length; i++) result = result & copy_(new File(src, files[i]), new File(dst, files[i]), force, recursive, true); return result; } // single file copy if (src.exists()) { // destination already exist ? if (dst.exists()) { // copy only if force flag == true if (force) { if (!delete(dst, true)) { System.err.println("Cannot copy '" + src.getAbsolutePath() + "' to '" + dst.getAbsolutePath() + "'"); System.err.println("Reason : destination cannot be overwritten."); System.err.println("Make sure it is not locked by another program (e.g. Eclipse)"); System.err.println("Also check that you have the rights to do this operation."); return false; } } else { System.err .println("Cannot copy '" + src.getAbsolutePath() + "' to '" + dst.getAbsolutePath() + "'"); System.err.println("The destination already exists."); System.err.println("Use the 'force' flag to force file copy."); return false; } } boolean lnk; try { lnk = isLink(src); } catch (IOException e) { lnk = false; } // link file and link supported by OS ? if (lnk && SystemUtil.isLinkSupported()) { // use OS dependent command (FIXME : replace by java 7 API when available) final Process process = SystemUtil.exec("cp -pRP " + src.getPath() + " " + dst.getPath()); int res = 1; if (process != null) { try { res = process.waitFor(); } catch (InterruptedException e1) { // ignore; } } // error while executing command if ((res != 0)) { System.err.println("FileUtil.copy(...) error while creating link '" + src.getPath() + "' to '" + dst.getPath() + "'"); if (process != null) { // get error output and redirect it final BufferedReader stderr = new BufferedReader( new InputStreamReader(process.getErrorStream())); try { System.err.println(stderr.readLine()); if (stderr.ready()) System.err.println(stderr.readLine()); } catch (IOException e) { // ignore } } else if (res == 1) System.err.println("Process interrupted."); return false; } return true; } // get data to copy from src final byte[] data = load(src, true); // source data correctly loaded if (data != null) { // save in dst if (save(dst, data, true)) { // and set the last modified info. dst.setLastModified(src.lastModified()); return true; } return false; } // cannot load input file System.err.println("Cannot copy '" + src.getAbsolutePath() + "' to '" + dst.getAbsolutePath() + "'"); System.err.println("Input file '" + src.getAbsolutePath() + "' data cannot be loaded !"); return false; } // missing input file System.err.println("Cannot copy '" + src.getAbsolutePath() + "' to '" + dst.getAbsolutePath() + "'"); System.err.println("Input file '" + src.getAbsolutePath() + "' not found !"); return false; } /** * Backup the specified file.<br> * Basically create a .bak version of the file. If the backup file already exist a postfix * number is automatically added. * * @param filename * file to backup * @return the backup filename is the operation success else return <code>null</code> */ public static String backup(String filename) { int postfix = 0; String backupName = filename + ".bak"; while (exists(backupName)) { backupName = filename + "_" + StringUtil.toString(postfix, 3) + ".bak"; postfix++; } if (FileUtil.copy(filename, backupName, true, false)) return backupName; return null; } /** * Transform all directory entries by their sub files list */ public static File[] explode(File[] files, FileFilter filter, boolean recursive, boolean wantHidden) { final List<File> result = new ArrayList<File>(); for (File file : files) { if (file.isDirectory()) getFiles(file, filter, recursive, true, false, wantHidden, result); else result.add(file); } return result.toArray(new File[result.size()]); } /** * @deprecated Use {@link #explode(List, FileFilter, boolean, boolean)} instead. */ @Deprecated public static List<File> explode(List<File> files, boolean recursive, boolean wantHidden) { return explode(files, null, recursive, wantHidden); } /** * Transform all directory entries by their sub files list */ public static List<File> explode(List<File> files, FileFilter filter, boolean recursive, boolean wantHidden) { final List<File> result = new ArrayList<File>(); for (File file : files) { if (file.isDirectory()) getFiles(file, filter, recursive, true, false, wantHidden, result); else result.add(file); } return result; } /** * Get file list from specified directory applying the specified parameters. * * @param extension * the wanted extension file (without the dot character).<br> * Set it to <code>null</code> to accept all files.<br> * If you only want files without extension then use an empty String extension. */ private static void getFiles(File folder, String extension, boolean ignoreExtensionCase, boolean recursive, List<File> list) { final File[] files = folder.listFiles(); if (files != null) { for (File file : files) { if (file.isDirectory()) { if (recursive) getFiles(file, extension, ignoreExtensionCase, recursive, list); } else if (extension != null) { final String fileExt = getFileExtension(file.getAbsolutePath(), false); if (ignoreExtensionCase) { if (extension.equalsIgnoreCase(fileExt)) list.add(file); } else { if (extension.equals(fileExt)) list.add(file); } } else list.add(file); } } } /** * Get file list from specified folder applying the specified parameters. */ public static File[] getFiles(File folder, String extension, boolean ignoreExtensionCase, boolean recursive) { final List<File> result = new ArrayList<File>(); getFiles(folder, extension, ignoreExtensionCase, recursive, result); return result.toArray(new File[result.size()]); } /** * Get file list from specified folder applying the specified parameters. */ public static String[] getFiles(String folder, String extension, boolean ignoreExtensionCase, boolean recursive) { final File[] files = getFiles(new File(getGenericPath(folder)), extension, ignoreExtensionCase, recursive); final String[] result = new String[files.length]; for (int i = 0; i < files.length; i++) result[i] = files[i].getPath(); return result; } /** * Get file list from specified directory applying the specified parameters. */ private static void getFiles(File f, FileFilter filter, boolean recursive, boolean wantFile, boolean wantDirectory, boolean wantHidden, List<File> list) { final File[] files = f.listFiles(filter); if (files != null) { for (File file : files) { if ((!file.isHidden()) || wantHidden) { if (file.isDirectory()) { if (wantDirectory) list.add(file); if (recursive) getFiles(file, filter, recursive, wantFile, wantDirectory, wantHidden, list); } else if (wantFile) list.add(file); } } } } /** * Get directory list from specified directory applying the specified parameters */ public static File[] getDirectories(File file, FileFilter filter, boolean recursive, boolean wantHidden) { final List<File> result = new ArrayList<File>(); getFiles(file, filter, recursive, false, true, wantHidden, result); return result.toArray(new File[result.size()]); } /** * Returns an array of file denoting content of specified directory and parameters. * * @param directory * The directory we want to retrieve content.<br> * @param filter * A file filter.<br> * If the given <code>filter</code> is <code>null</code> then all pathnames are accepted. * Otherwise, a pathname satisfies the filter if and only if the value <code>true</code> results when the * <code>{@link FileFilter#accept(java.io.File)}</code> method of the * filter is invoked on the pathname. * @param recursive * If <code>true</code> then content from sub folder is also returned. * @param wantDirectory * If <code>true</code> then directory entries are also returned. * @param wantHidden * If <code>true</code> then file or directory with <code>hidden</code> attribute are * also returned. * @see File#listFiles(FileFilter) */ public static File[] getFiles(File directory, FileFilter filter, boolean recursive, boolean wantDirectory, boolean wantHidden) { final List<File> result = new ArrayList<File>(); getFiles(directory, filter, recursive, true, wantDirectory, wantHidden, result); return result.toArray(new File[result.size()]); } /** * Returns an array of file path denoting content of specified directory and parameters * (String format). * * @param directory * The directory we want to retrieve content.<br> * @param filter * A file filter.<br> * If the given <code>filter</code> is <code>null</code> then all files are accepted. * Otherwise, a file satisfies the filter if and only if the value <code>true</code> results when the * <code>{@link FileFilter#accept(java.io.File)}</code> method of the * filter is invoked on the pathname. * @param recursive * If <code>true</code> then content from sub folder is also returned. * @param wantDirectory * If <code>true</code> then directory entries are also returned. * @param wantHidden * If <code>true</code> then file or directory with <code>hidden</code> attribute are * also returned. */ public static String[] getFiles(String directory, FileFilter filter, boolean recursive, boolean wantDirectory, boolean wantHidden) { final File[] files = getFiles(new File(getGenericPath(directory)), filter, recursive, wantDirectory, wantHidden); final String[] result = new String[files.length]; for (int i = 0; i < files.length; i++) result[i] = files[i].getPath(); return result; } /** * @deprecated Use {@link #getFiles(File, FileFilter, boolean, boolean, boolean)} instead. */ @Deprecated public static ArrayList<File> getFileList(String path, FileFilter filter, boolean recursive, boolean wantDirectory, boolean wantHidden) { final ArrayList<File> result = new ArrayList<File>(); getFiles(new File(getGenericPath(path)), filter, recursive, true, wantDirectory, wantHidden, result); return result; } /** * @deprecated Use {@link #getFiles(File, FileFilter, boolean, boolean, boolean)} instead. */ @Deprecated public static ArrayList<File> getFileList(File file, FileFilter filter, boolean recursive, boolean wantDirectory, boolean wantHidden) { final ArrayList<File> result = new ArrayList<File>(); getFiles(file, filter, recursive, true, wantDirectory, wantHidden, result); return result; } /** * @deprecated Use {@link #getFiles(File, FileFilter, boolean, boolean, boolean)} instead. */ @Deprecated public static ArrayList<File> getFileList(String path, FileFilter filter, boolean recursive, boolean wantHidden) { return getFileList(path, filter, recursive, false, wantHidden); } /** * @deprecated Use {@link #getFiles(File, FileFilter, boolean, boolean, boolean)} instead. */ @Deprecated public static ArrayList<File> getFileList(File file, FileFilter filter, boolean recursive, boolean wantHidden) { return getFileList(file, filter, recursive, false, wantHidden); } /** * @deprecated Use {@link #getFiles(File, FileFilter, boolean, boolean, boolean)} instead. */ @Deprecated public static ArrayList<File> getFileList(String path, boolean recursive, boolean wantDirectory, boolean wantHidden) { return getFileList(new File(getGenericPath(path)), null, recursive, wantDirectory, wantHidden); } /** * @deprecated Use {@link #getFiles(File, FileFilter, boolean, boolean, boolean)} instead. */ @Deprecated public static ArrayList<File> getFileList(File file, boolean recursive, boolean wantDirectory, boolean wantHidden) { return getFileList(file, null, recursive, wantDirectory, wantHidden); } /** * @deprecated Use {@link #getFiles(File, FileFilter, boolean, boolean, boolean)} instead. */ @Deprecated public static ArrayList<File> getFileList(File file, boolean recursive, boolean wantHidden) { return getFileList(file, recursive, false, wantHidden); } /** * @deprecated Use {@link #getFiles(File, FileFilter, boolean, boolean, boolean)} instead. */ @Deprecated public static ArrayList<File> getFileList(String path, boolean recursive, boolean wantHidden) { return getFileList(path, recursive, false, wantHidden); } /** * @deprecated Use {@link #getFiles(String, FileFilter, boolean, boolean, boolean)} instead. */ @Deprecated public static ArrayList<String> getFileListAsString(String path, FileFilter filter, boolean recursive, boolean wantDirectory, boolean wantHidden) { final ArrayList<File> files = getFileList(path, filter, recursive, wantDirectory, wantHidden); final ArrayList<String> result = new ArrayList<String>(); for (File file : files) result.add(file.getPath()); return result; } /** * @deprecated Use {@link #getFiles(String, FileFilter, boolean, boolean, boolean)} instead. */ @Deprecated public static ArrayList<String> getFileListAsString(String path, boolean recursive, boolean wantDirectory, boolean wantHidden) { return getFileListAsString(path, null, recursive, wantDirectory, wantHidden); } /** * @deprecated Use {@link #getFiles(String, FileFilter, boolean, boolean, boolean)} instead. */ @Deprecated public static ArrayList<String> getFileListAsString(String path, FileFilter filter, boolean recursive, boolean wantHidden) { return getFileListAsString(path, filter, recursive, false, wantHidden); } /** * @deprecated Use {@link #getFiles(String, FileFilter, boolean, boolean, boolean)} instead. */ @Deprecated public static ArrayList<String> getFileListAsString(String path, boolean recursive, boolean wantHidden) { return getFileListAsString(path, recursive, false, wantHidden); } /** * Return true if the file described by specified path exists * * @deprecated use {@link #exists(String)} instead */ @Deprecated public static boolean exist(String path) { return exists(path); } /** * Return true if the file described by specified path exists */ public static boolean exists(String path) { return new File(getGenericPath(path)).exists(); } /** * Return true if the specified file is a directory */ public static boolean isDirectory(String path) { return new File(getGenericPath(path)).isDirectory(); } /** * Return true if the specified file is a link<br> * Be careful, it does work in almost case, but not all * * @throws IOException */ public static boolean isLink(String path) throws IOException { return isLink(new File(getGenericPath(path))); } /** * Return true if the specified file is a link<br> * Be careful, it does work in almost case, but not all * * @throws IOException */ public static boolean isLink(File file) throws IOException { if (file == null) return false; final File canon; if (file.getParent() == null) canon = file; else canon = new File(file.getParentFile().getCanonicalFile(), file.getName()); // we want to ignore case whatever system does return !canon.getCanonicalFile().getAbsolutePath().equalsIgnoreCase(canon.getAbsolutePath()); } public static boolean delete(String path, boolean recursive) { return delete(new File(getGenericPath(path)), recursive); } public static boolean delete(File f, boolean recursive) { boolean result = true; if (f.isDirectory()) { final File[] files = f.listFiles(); // can return null... if (files != null) { // delete files for (File file : files) { if (file.isDirectory()) { if (recursive) result = result & delete(file, true); } else result = result & file.delete(); } } // then delete empty directory result = result & f.delete(); } else if (f.exists()) { final long start = System.currentTimeMillis(); // we can need that first to delete file if (!f.setWritable(true, false)) f.setWritable(true, true); result = f.delete(); // retry for locked file (we try for 15s max) while ((!result) && (System.currentTimeMillis() - start) < (10 * 1000)) { // can help for file deletion... System.gc(); ThreadUtil.sleep(1000); // may help if (!f.setWritable(true, false)) f.setWritable(true, true); result = f.delete(); } } return result; } }