/*
* 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;
}
}