2012-06-25 17:29:16 +02:00
|
|
|
package processing.app.helpers;
|
|
|
|
|
2015-05-21 16:47:50 +02:00
|
|
|
import org.apache.commons.compress.utils.IOUtils;
|
|
|
|
|
2013-10-14 17:31:35 +02:00
|
|
|
import java.io.*;
|
2015-09-16 14:51:37 +02:00
|
|
|
import java.nio.file.Files;
|
|
|
|
import java.nio.file.Paths;
|
2015-06-18 12:22:55 +02:00
|
|
|
import java.util.*;
|
2013-06-27 17:35:34 +02:00
|
|
|
import java.util.regex.Pattern;
|
2012-06-25 17:29:16 +02:00
|
|
|
|
|
|
|
public class FileUtils {
|
2012-10-18 16:49:14 +02:00
|
|
|
|
2013-10-14 14:48:41 +02:00
|
|
|
private static final List<String> SOURCE_CONTROL_FOLDERS = Arrays.asList("CVS", "RCS", ".git", ".svn", ".hg", ".bzr");
|
2013-06-27 17:35:34 +02:00
|
|
|
private static final Pattern BACKSLASH = Pattern.compile("\\\\");
|
|
|
|
|
2012-06-25 17:29:16 +02:00
|
|
|
/**
|
2012-10-18 16:49:14 +02:00
|
|
|
* Checks, whether the child directory is a subdirectory of the base directory.
|
2013-06-27 17:35:34 +02:00
|
|
|
*
|
|
|
|
* @param base the base directory.
|
|
|
|
* @param child the suspected child directory.
|
2012-06-25 17:29:16 +02:00
|
|
|
* @return true, if the child is a subdirectory of the base directory.
|
|
|
|
*/
|
2012-07-03 17:26:15 +02:00
|
|
|
public static boolean isSubDirectory(File base, File child) {
|
|
|
|
try {
|
|
|
|
base = base.getCanonicalFile();
|
|
|
|
child = child.getCanonicalFile();
|
|
|
|
} catch (IOException e) {
|
|
|
|
return false;
|
|
|
|
}
|
2012-06-25 17:29:16 +02:00
|
|
|
|
|
|
|
File parentFile = child;
|
|
|
|
while (parentFile != null) {
|
|
|
|
if (base.equals(parentFile)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
parentFile = parentFile.getParentFile();
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2012-10-18 16:49:14 +02:00
|
|
|
|
2012-12-17 11:25:45 +01:00
|
|
|
public static void copyFile(File source, File dest) throws IOException {
|
|
|
|
FileInputStream fis = null;
|
|
|
|
FileOutputStream fos = null;
|
|
|
|
try {
|
|
|
|
fis = new FileInputStream(source);
|
|
|
|
fos = new FileOutputStream(dest);
|
|
|
|
byte[] buf = new byte[4096];
|
|
|
|
int readBytes = -1;
|
|
|
|
while ((readBytes = fis.read(buf, 0, buf.length)) != -1) {
|
|
|
|
fos.write(buf, 0, readBytes);
|
|
|
|
}
|
|
|
|
} finally {
|
2015-05-21 16:47:50 +02:00
|
|
|
IOUtils.closeQuietly(fis);
|
|
|
|
IOUtils.closeQuietly(fos);
|
2012-12-17 11:25:45 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-10-18 16:49:14 +02:00
|
|
|
public static void copy(File sourceFolder, File destFolder) throws IOException {
|
|
|
|
for (File file : sourceFolder.listFiles()) {
|
|
|
|
File destFile = new File(destFolder, file.getName());
|
|
|
|
if (file.isDirectory()) {
|
|
|
|
if (!destFile.mkdir()) {
|
|
|
|
throw new IOException("Unable to create folder: " + destFile);
|
|
|
|
}
|
|
|
|
copy(file, destFile);
|
|
|
|
} else {
|
2012-12-17 11:25:45 +01:00
|
|
|
copyFile(file, destFile);
|
2012-10-18 16:49:14 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void recursiveDelete(File file) {
|
2015-03-25 17:40:50 +01:00
|
|
|
if (file == null) {
|
2012-10-19 10:35:48 +02:00
|
|
|
return;
|
2015-03-25 17:40:50 +01:00
|
|
|
}
|
2012-10-18 16:49:14 +02:00
|
|
|
if (file.isDirectory()) {
|
2015-04-29 11:57:27 +02:00
|
|
|
File[] files = file.listFiles();
|
|
|
|
if (files == null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
for (File current : files) {
|
2014-05-16 01:05:35 +02:00
|
|
|
recursiveDelete(current);
|
2015-03-25 17:40:50 +01:00
|
|
|
}
|
2012-10-18 16:49:14 +02:00
|
|
|
}
|
2015-05-14 19:36:37 +02:00
|
|
|
file.delete();
|
2012-10-18 16:49:14 +02:00
|
|
|
}
|
|
|
|
|
2012-10-19 10:35:48 +02:00
|
|
|
public static File createTempFolder() throws IOException {
|
2015-09-16 14:51:37 +02:00
|
|
|
return createTempFolder(new File(System.getProperty("java.io.tmpdir")));
|
2015-02-27 14:47:38 +01:00
|
|
|
}
|
|
|
|
|
2015-09-16 14:51:37 +02:00
|
|
|
public static File createTempFolder(File parent) throws IOException {
|
|
|
|
return createTempFolder(parent, "arduino_");
|
|
|
|
}
|
|
|
|
|
|
|
|
public static File createTempFolder(File parent, String prefix) throws IOException {
|
|
|
|
return createTempFolder(parent, prefix, Integer.toString(new Random().nextInt(1000000)));
|
|
|
|
}
|
|
|
|
|
|
|
|
public static File createTempFolder(String prefix) throws IOException {
|
|
|
|
return createTempFolder(new File(System.getProperty("java.io.tmpdir")), prefix);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static File createTempFolder(String prefix, String suffix) throws IOException {
|
|
|
|
return createTempFolder(new File(System.getProperty("java.io.tmpdir")), prefix, suffix);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static File createTempFolder(File parent, String prefix, String suffix) throws IOException {
|
|
|
|
return Files.createDirectories(Paths.get(parent.getAbsolutePath(), prefix + suffix)).toFile();
|
2012-10-19 10:35:48 +02:00
|
|
|
}
|
|
|
|
|
2013-01-16 14:04:30 +01:00
|
|
|
//
|
|
|
|
// Compute relative path to "target" from a directory "origin".
|
|
|
|
//
|
|
|
|
// If "origin" is not absolute, it is relative from the current directory.
|
|
|
|
// If "target" is not absolute, it is relative from "origin".
|
|
|
|
//
|
|
|
|
// by Shigeru KANEMOTO at SWITCHSCIENCE.
|
|
|
|
//
|
|
|
|
public static String relativePath(String origin, String target) {
|
|
|
|
try {
|
|
|
|
origin = (new File(origin)).getCanonicalPath();
|
|
|
|
File targetFile = new File(target);
|
|
|
|
if (targetFile.isAbsolute())
|
|
|
|
target = targetFile.getCanonicalPath();
|
|
|
|
else
|
|
|
|
target = (new File(origin, target)).getCanonicalPath();
|
|
|
|
} catch (IOException e) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (origin.equals(target)) {
|
|
|
|
// origin and target is identical.
|
|
|
|
return ".";
|
|
|
|
}
|
|
|
|
|
|
|
|
if (origin.equals(File.separator)) {
|
|
|
|
// origin is root.
|
|
|
|
return "." + target;
|
|
|
|
}
|
|
|
|
|
|
|
|
String prefix = "";
|
|
|
|
String root = File.separator;
|
|
|
|
|
|
|
|
if (System.getProperty("os.name").indexOf("Windows") != -1) {
|
|
|
|
if (origin.startsWith("\\\\") || target.startsWith("\\\\")) {
|
|
|
|
// Windows UNC path not supported.
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
char originLetter = origin.charAt(0);
|
|
|
|
char targetLetter = target.charAt(0);
|
|
|
|
if (Character.isLetter(originLetter) && Character.isLetter(targetLetter)) {
|
|
|
|
// Windows only
|
|
|
|
if (originLetter != targetLetter) {
|
|
|
|
// Drive letters differ
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
prefix = "" + originLetter + ':';
|
|
|
|
root = prefix + File.separator;
|
|
|
|
}
|
|
|
|
|
|
|
|
String relative = "";
|
|
|
|
while (!target.startsWith(origin + File.separator)) {
|
|
|
|
origin = (new File(origin)).getParent();
|
|
|
|
if (origin.equals(root))
|
|
|
|
origin = prefix;
|
|
|
|
relative += "..";
|
|
|
|
relative += File.separator;
|
|
|
|
}
|
|
|
|
|
|
|
|
return relative + target.substring(origin.length() + 1);
|
|
|
|
}
|
2013-06-27 17:35:34 +02:00
|
|
|
|
|
|
|
public static String getLinuxPathFrom(File file) {
|
|
|
|
return BACKSLASH.matcher(file.getAbsolutePath()).replaceAll("/");
|
|
|
|
}
|
2013-10-14 14:48:41 +02:00
|
|
|
|
|
|
|
public static boolean isSCCSOrHiddenFile(File file) {
|
2015-05-27 11:26:00 +02:00
|
|
|
return isSCCSFolder(file) || isHiddenFile(file);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static boolean isHiddenFile(File file) {
|
|
|
|
return file.isHidden() || file.getName().charAt(0) == '.';
|
|
|
|
}
|
|
|
|
|
|
|
|
public static boolean isSCCSFolder(File file) {
|
|
|
|
return file.isDirectory() && SOURCE_CONTROL_FOLDERS.contains(file.getName());
|
2013-10-14 14:48:41 +02:00
|
|
|
}
|
2013-10-14 17:31:35 +02:00
|
|
|
|
|
|
|
public static String readFileToString(File file) throws IOException {
|
2015-06-19 17:38:10 +02:00
|
|
|
return readFileToString(file, "UTF-8");
|
|
|
|
}
|
|
|
|
|
|
|
|
public static String readFileToString(File file, String encoding) throws IOException {
|
2013-10-14 17:31:35 +02:00
|
|
|
BufferedReader reader = null;
|
|
|
|
try {
|
2015-06-19 17:38:10 +02:00
|
|
|
reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), encoding));
|
2013-10-14 17:31:35 +02:00
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
String line;
|
|
|
|
while ((line = reader.readLine()) != null) {
|
|
|
|
sb.append(line).append("\n");
|
|
|
|
}
|
|
|
|
return sb.toString();
|
|
|
|
} finally {
|
2015-05-21 16:47:50 +02:00
|
|
|
IOUtils.closeQuietly(reader);
|
2013-10-14 17:31:35 +02:00
|
|
|
}
|
|
|
|
}
|
2013-12-09 00:10:36 +01:00
|
|
|
|
2015-06-18 12:22:55 +02:00
|
|
|
public static List<String> readFileToListOfStrings(File file) throws IOException {
|
|
|
|
List<String> strings = new LinkedList<String>();
|
|
|
|
BufferedReader reader = null;
|
|
|
|
try {
|
|
|
|
reader = new BufferedReader(new FileReader(file));
|
|
|
|
String line;
|
|
|
|
while ((line = reader.readLine()) != null) {
|
|
|
|
line = line.replaceAll("\r", "").replaceAll("\n", "").replaceAll(" ", "");
|
|
|
|
strings.add(line);
|
|
|
|
}
|
|
|
|
return strings;
|
|
|
|
} finally {
|
|
|
|
if (reader != null) {
|
|
|
|
reader.close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-12-09 00:10:36 +01:00
|
|
|
/**
|
|
|
|
* Returns true if the given file has any of the given extensions.
|
2015-06-18 12:22:55 +02:00
|
|
|
*
|
|
|
|
* @param file File whose name to look at
|
|
|
|
* @param extensions Extensions to consider (just the extension, without the
|
|
|
|
* dot). Should all be lowercase, case insensitive matching
|
|
|
|
* is used.
|
2013-12-09 00:10:36 +01:00
|
|
|
*/
|
|
|
|
public static boolean hasExtension(File file, String... extensions) {
|
|
|
|
return hasExtension(file, Arrays.asList(extensions));
|
|
|
|
}
|
|
|
|
|
|
|
|
public static boolean hasExtension(File file, List<String> extensions) {
|
2015-06-18 12:22:55 +02:00
|
|
|
String pieces[] = file.getName().split("\\.");
|
|
|
|
if (pieces.length < 2) {
|
|
|
|
return false;
|
|
|
|
}
|
2013-12-09 00:10:36 +01:00
|
|
|
|
2015-06-18 12:22:55 +02:00
|
|
|
String extension = pieces[pieces.length - 1];
|
2013-12-09 00:10:36 +01:00
|
|
|
|
2015-06-18 12:22:55 +02:00
|
|
|
return extensions.contains(extension.toLowerCase());
|
2013-12-09 00:10:36 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Recursively find all files in a folder with the specified
|
|
|
|
* extension. Excludes hidden files and folders and
|
|
|
|
* source control folders.
|
|
|
|
*
|
2015-06-18 12:22:55 +02:00
|
|
|
* @param folder Folder to look into
|
|
|
|
* @param recursive <b>true</b> will recursively find all files in sub-folders
|
|
|
|
* @param extensions A list of file extensions to search (just the extension,
|
|
|
|
* without the dot). Should all be lowercase, case
|
|
|
|
* insensitive matching is used. If no extensions are
|
|
|
|
* passed, all files are returned.
|
2013-12-09 00:10:36 +01:00
|
|
|
* @return
|
|
|
|
*/
|
|
|
|
public static List<File> listFiles(File folder, boolean recursive,
|
|
|
|
String... extensions) {
|
|
|
|
return listFiles(folder, recursive, Arrays.asList(extensions));
|
|
|
|
}
|
|
|
|
|
|
|
|
public static List<File> listFiles(File folder, boolean recursive,
|
|
|
|
List<String> extensions) {
|
|
|
|
List<File> result = new ArrayList<File>();
|
|
|
|
|
|
|
|
for (File file : folder.listFiles()) {
|
|
|
|
if (isSCCSOrHiddenFile(file))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (file.isDirectory()) {
|
|
|
|
if (recursive)
|
|
|
|
result.addAll(listFiles(file, true, extensions));
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (extensions.isEmpty() || hasExtension(file, extensions))
|
|
|
|
result.add(file);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2015-03-25 17:40:50 +01:00
|
|
|
public static File newFile(File parent, String... parts) {
|
|
|
|
File result = parent;
|
|
|
|
for (String part : parts) {
|
|
|
|
result = new File(result, part);
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2015-05-04 17:44:16 +02:00
|
|
|
public static boolean deleteIfExists(File file) {
|
|
|
|
if (file == null) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return file.delete();
|
|
|
|
}
|
2013-12-09 00:10:36 +01:00
|
|
|
|
2012-06-25 17:29:16 +02:00
|
|
|
}
|