mirror of
https://github.com/mitb-archive/filebot
synced 2025-03-09 22:09:47 -04:00
* symlink using relative link targets if possible but default to absolute paths for cross-volume absolute symlinks if necessary
This commit is contained in:
parent
cf11cfecb0
commit
be22317f41
@ -1,130 +1,124 @@
|
||||
|
||||
package net.sourceforge.filebot;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import net.sourceforge.tuned.FileUtilities;
|
||||
|
||||
|
||||
public enum StandardRenameAction implements RenameAction {
|
||||
|
||||
|
||||
MOVE {
|
||||
|
||||
|
||||
@Override
|
||||
public File rename(File from, File to) throws Exception {
|
||||
return FileUtilities.moveRename(from, to);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
COPY {
|
||||
|
||||
|
||||
@Override
|
||||
public File rename(File from, File to) throws Exception {
|
||||
return FileUtilities.copyAs(from, to);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
KEEPLINK {
|
||||
|
||||
|
||||
@Override
|
||||
public File rename(File from, File to) throws Exception {
|
||||
File destionation = FileUtilities.resolveDestination(from, to, true);
|
||||
|
||||
|
||||
// move file and the create a symlink to the new location via NIO.2
|
||||
try {
|
||||
java.nio.file.Files.move(from.toPath(), destionation.toPath());
|
||||
java.nio.file.Files.createSymbolicLink(from.toPath(), destionation.toPath());
|
||||
FileUtilities.createRelativeSymlink(from, destionation, true);
|
||||
} catch (LinkageError e) {
|
||||
throw new Exception("Unsupported Operation: move, createSymbolicLink");
|
||||
}
|
||||
|
||||
|
||||
return destionation;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
SYMLINK {
|
||||
|
||||
|
||||
@Override
|
||||
public File rename(File from, File to) throws Exception {
|
||||
File destionation = FileUtilities.resolveDestination(from, to, true);
|
||||
|
||||
|
||||
// create symlink via NIO.2
|
||||
try {
|
||||
java.nio.file.Files.createSymbolicLink(destionation.toPath(), from.toPath());
|
||||
return FileUtilities.createRelativeSymlink(destionation, from, true);
|
||||
} catch (LinkageError e) {
|
||||
throw new Exception("Unsupported Operation: createSymbolicLink");
|
||||
}
|
||||
|
||||
return destionation;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
HARDLINK {
|
||||
|
||||
|
||||
@Override
|
||||
public File rename(File from, File to) throws Exception {
|
||||
File destionation = FileUtilities.resolveDestination(from, to, true);
|
||||
|
||||
|
||||
// create hardlink via NIO.2
|
||||
try {
|
||||
java.nio.file.Files.createLink(destionation.toPath(), from.toPath());
|
||||
} catch (LinkageError e) {
|
||||
throw new Exception("Unsupported Operation: createLink");
|
||||
}
|
||||
|
||||
|
||||
return destionation;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
RENAME {
|
||||
|
||||
|
||||
@Override
|
||||
public File rename(File from, File to) throws IOException {
|
||||
// rename only the filename
|
||||
File dest = new File(from.getParentFile(), to.getName());
|
||||
|
||||
|
||||
if (!from.renameTo(dest))
|
||||
throw new IOException("Rename failed: " + dest);
|
||||
|
||||
|
||||
return dest;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
TEST {
|
||||
|
||||
|
||||
@Override
|
||||
public File rename(File from, File to) throws IOException {
|
||||
return FileUtilities.resolveDestination(from, to, false);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
public String getDisplayName() {
|
||||
switch (this) {
|
||||
case MOVE:
|
||||
return "Rename";
|
||||
case COPY:
|
||||
return "Copy";
|
||||
case KEEPLINK:
|
||||
return "Keeplink";
|
||||
case SYMLINK:
|
||||
return "Symlink";
|
||||
case HARDLINK:
|
||||
return "Hardlink";
|
||||
default:
|
||||
return null;
|
||||
case MOVE:
|
||||
return "Rename";
|
||||
case COPY:
|
||||
return "Copy";
|
||||
case KEEPLINK:
|
||||
return "Keeplink";
|
||||
case SYMLINK:
|
||||
return "Symlink";
|
||||
case HARDLINK:
|
||||
return "Hardlink";
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static StandardRenameAction forName(String action) {
|
||||
for (StandardRenameAction it : values()) {
|
||||
if (it.name().equalsIgnoreCase(action))
|
||||
return it;
|
||||
}
|
||||
|
||||
|
||||
throw new IllegalArgumentException("Illegal rename action: " + action);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,7 +1,5 @@
|
||||
|
||||
package net.sourceforge.tuned;
|
||||
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
@ -40,13 +38,12 @@ import org.w3c.dom.Document;
|
||||
import com.ibm.icu.text.CharsetDetector;
|
||||
import com.ibm.icu.text.CharsetMatch;
|
||||
|
||||
|
||||
public final class FileUtilities {
|
||||
|
||||
|
||||
public static File moveRename(File source, File destination) throws IOException {
|
||||
// resolve destination
|
||||
destination = resolveDestination(source, destination, true);
|
||||
|
||||
|
||||
if (source.isDirectory()) {
|
||||
// move folder
|
||||
org.apache.commons.io.FileUtils.moveDirectory(source, destination);
|
||||
@ -58,15 +55,14 @@ public final class FileUtilities {
|
||||
org.apache.commons.io.FileUtils.moveFile(source, destination); // use "copy and delete" as fallback if standard rename fails
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return destination;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static File copyAs(File source, File destination) throws IOException {
|
||||
// resolve destination
|
||||
destination = resolveDestination(source, destination, true);
|
||||
|
||||
|
||||
if (source.isDirectory()) {
|
||||
// copy folder
|
||||
org.apache.commons.io.FileUtils.copyDirectory(source, destination);
|
||||
@ -78,104 +74,110 @@ public final class FileUtilities {
|
||||
org.apache.commons.io.FileUtils.copyFile(source, destination);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return destination;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static File resolveDestination(File source, File destination, boolean mkdirs) throws IOException {
|
||||
// resolve destination
|
||||
if (!destination.isAbsolute()) {
|
||||
// same folder, different name
|
||||
destination = new File(source.getParentFile(), destination.getPath());
|
||||
}
|
||||
|
||||
|
||||
// make sure we that we can create the destination folder structure
|
||||
File destinationFolder = destination.getParentFile();
|
||||
|
||||
|
||||
// create parent folder if necessary
|
||||
if (mkdirs && !destinationFolder.isDirectory() && !destinationFolder.mkdirs()) {
|
||||
throw new IOException("Failed to create folder: " + destinationFolder);
|
||||
}
|
||||
|
||||
|
||||
return destination;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static File createRelativeSymlink(File link, File target, boolean relativize) throws IOException {
|
||||
if (relativize) {
|
||||
try {
|
||||
target = link.getParentFile().toPath().relativize(target.toPath()).toFile();
|
||||
} catch (Throwable e) {
|
||||
// unable to relativize link target
|
||||
}
|
||||
}
|
||||
|
||||
// create symlink via NIO.2
|
||||
return java.nio.file.Files.createSymbolicLink(link.toPath(), target.toPath()).toFile();
|
||||
}
|
||||
|
||||
public static boolean delete(File file) {
|
||||
// delete files or files
|
||||
return org.apache.commons.io.FileUtils.deleteQuietly(file);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static byte[] readFile(File source) throws IOException {
|
||||
InputStream in = new FileInputStream(source);
|
||||
|
||||
|
||||
try {
|
||||
long size = source.length();
|
||||
if (size < 0 || size > Integer.MAX_VALUE) {
|
||||
throw new IllegalArgumentException("Unable to read file: " + source);
|
||||
}
|
||||
|
||||
|
||||
byte[] data = new byte[(int) size];
|
||||
|
||||
|
||||
int position = 0;
|
||||
int read = 0;
|
||||
|
||||
|
||||
while (position < data.length && (read = in.read(data, position, data.length - position)) >= 0) {
|
||||
position += read;
|
||||
}
|
||||
|
||||
|
||||
return data;
|
||||
} finally {
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static String readAll(Reader source) throws IOException {
|
||||
StringBuilder text = new StringBuilder();
|
||||
char[] buffer = new char[2048];
|
||||
|
||||
|
||||
int read = 0;
|
||||
while ((read = source.read(buffer)) >= 0) {
|
||||
text.append(buffer, 0, read);
|
||||
}
|
||||
|
||||
|
||||
return text.toString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void writeFile(ByteBuffer data, File destination) throws IOException {
|
||||
FileChannel fileChannel = new FileOutputStream(destination).getChannel();
|
||||
|
||||
|
||||
try {
|
||||
fileChannel.write(data);
|
||||
} finally {
|
||||
fileChannel.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static Reader createTextReader(File file) throws IOException {
|
||||
CharsetDetector detector = new CharsetDetector();
|
||||
detector.setDeclaredEncoding("UTF-8"); // small boost for UTF-8 as default encoding
|
||||
detector.setText(new BufferedInputStream(new FileInputStream(file)));
|
||||
|
||||
|
||||
CharsetMatch charset = detector.detect();
|
||||
if (charset != null)
|
||||
return charset.getReader();
|
||||
|
||||
|
||||
// assume UTF-8 by default
|
||||
return new InputStreamReader(new FileInputStream(file), "UTF-8");
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static String getText(ByteBuffer data) throws IOException {
|
||||
CharsetDetector detector = new CharsetDetector();
|
||||
detector.setDeclaredEncoding("UTF-8"); // small boost for UTF-8 as default encoding
|
||||
detector.setText(new ByteBufferInputStream(data));
|
||||
|
||||
|
||||
CharsetMatch charset = detector.detect();
|
||||
if (charset != null) {
|
||||
try {
|
||||
@ -184,11 +186,11 @@ public final class FileUtilities {
|
||||
throw new IOException("Failed to read text", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// assume UTF-8 by default
|
||||
return Charset.forName("UTF-8").decode(data).toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Pattern used for matching file extensions.
|
||||
*
|
||||
@ -196,35 +198,31 @@ public final class FileUtilities {
|
||||
*/
|
||||
public static final Pattern EXTENSION = Pattern.compile("(?<=.[.])\\p{Alnum}+$");
|
||||
public static final String UNC_PREFIX = "\\\\";
|
||||
|
||||
|
||||
|
||||
public static String getExtension(File file) {
|
||||
if (file.isDirectory())
|
||||
return null;
|
||||
|
||||
|
||||
return getExtension(file.getName());
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static String getExtension(String name) {
|
||||
Matcher matcher = EXTENSION.matcher(name);
|
||||
|
||||
|
||||
if (matcher.find()) {
|
||||
// extension without leading '.'
|
||||
return matcher.group();
|
||||
}
|
||||
|
||||
|
||||
// no extension
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static boolean hasExtension(File file, String... extensions) {
|
||||
// avoid native call for speed, if possible
|
||||
return hasExtension(file.getName(), extensions) && !file.isDirectory();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static boolean hasExtension(String filename, String... extensions) {
|
||||
for (String it : extensions) {
|
||||
if (filename.length() - it.length() >= 2 && filename.charAt(filename.length() - it.length() - 1) == '.') {
|
||||
@ -234,78 +232,70 @@ public final class FileUtilities {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static String getNameWithoutExtension(String name) {
|
||||
Matcher matcher = EXTENSION.matcher(name);
|
||||
|
||||
|
||||
if (matcher.find()) {
|
||||
return name.substring(0, matcher.start() - 1);
|
||||
}
|
||||
|
||||
|
||||
// no extension, return given name
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static String getName(File file) {
|
||||
if (file.getName().isEmpty() || UNC_PREFIX.equals(file.getParent()))
|
||||
return getFolderName(file);
|
||||
|
||||
|
||||
return getNameWithoutExtension(file.getName());
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static String getFolderName(File file) {
|
||||
if (UNC_PREFIX.equals(file.getParent()))
|
||||
return file.toString();
|
||||
|
||||
|
||||
if (file.getName().length() > 0)
|
||||
return file.getName();
|
||||
|
||||
|
||||
// file might be a drive (only has a path, but no name)
|
||||
return replacePathSeparators(file.toString(), "");
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static boolean isDerived(File derivate, File prime) {
|
||||
return isDerived(getName(derivate), prime);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static boolean isDerived(String derivate, File prime) {
|
||||
String base = getName(prime).trim().toLowerCase();
|
||||
derivate = derivate.trim().toLowerCase();
|
||||
return derivate.startsWith(base);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static boolean isDerivedByExtension(File derivate, File prime) {
|
||||
return isDerivedByExtension(getName(derivate), prime);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static boolean isDerivedByExtension(String derivate, File prime) {
|
||||
String base = getName(prime).trim().toLowerCase();
|
||||
derivate = derivate.trim().toLowerCase();
|
||||
|
||||
|
||||
if (derivate.equals(base))
|
||||
return true;
|
||||
|
||||
|
||||
while (derivate.length() > base.length() && getExtension(derivate) != null) {
|
||||
derivate = getNameWithoutExtension(derivate);
|
||||
|
||||
|
||||
if (derivate.equals(base))
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static boolean containsOnly(Collection<File> files, FileFilter filter) {
|
||||
if (files.isEmpty()) {
|
||||
return false;
|
||||
@ -316,11 +306,10 @@ public final class FileUtilities {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static List<File> filter(Iterable<File> files, FileFilter... filters) {
|
||||
List<File> accepted = new ArrayList<File>();
|
||||
|
||||
|
||||
for (File file : files) {
|
||||
for (FileFilter filter : filters) {
|
||||
if (filter.accept(file)) {
|
||||
@ -329,19 +318,17 @@ public final class FileUtilities {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return accepted;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static FileFilter not(FileFilter filter) {
|
||||
return new NotFileFilter(filter);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static List<File> flatten(Iterable<File> roots, int maxDepth, boolean listHiddenFiles) {
|
||||
List<File> files = new ArrayList<File>();
|
||||
|
||||
|
||||
// unfold/flatten file tree
|
||||
for (File root : roots) {
|
||||
if (root.isDirectory()) {
|
||||
@ -350,28 +337,25 @@ public final class FileUtilities {
|
||||
files.add(root);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static List<File> listPath(File file) {
|
||||
return listPathTail(file, Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static List<File> listPathTail(File file, int tailSize) {
|
||||
LinkedList<File> nodes = new LinkedList<File>();
|
||||
|
||||
|
||||
File node = file;
|
||||
for (int i = 0; node != null && i < tailSize && !UNC_PREFIX.equals(node.toString()); i++, node = node.getParentFile()) {
|
||||
nodes.addFirst(node);
|
||||
}
|
||||
|
||||
|
||||
return nodes;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static File getRelativePathTail(File file, int tailSize) {
|
||||
File f = null;
|
||||
for (File it : listPathTail(file, tailSize)) {
|
||||
@ -381,28 +365,26 @@ public final class FileUtilities {
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static List<File> listFiles(Iterable<File> folders, int maxDepth, boolean listHiddenFiles) {
|
||||
List<File> files = new ArrayList<File>();
|
||||
|
||||
|
||||
// collect files from directory tree
|
||||
for (File folder : folders) {
|
||||
listFiles(folder, 0, files, maxDepth, listHiddenFiles);
|
||||
}
|
||||
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static void listFiles(File folder, int depth, List<File> files, int maxDepth, boolean listHiddenFiles) {
|
||||
if (depth > maxDepth)
|
||||
return;
|
||||
|
||||
|
||||
for (File file : folder.listFiles()) {
|
||||
if (!listHiddenFiles && file.isHidden()) // ignore hidden files
|
||||
continue;
|
||||
|
||||
|
||||
if (file.isDirectory()) {
|
||||
listFiles(file, depth + 1, files, maxDepth, listHiddenFiles);
|
||||
} else {
|
||||
@ -410,111 +392,104 @@ public final class FileUtilities {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static SortedMap<File, List<File>> mapByFolder(Iterable<File> files) {
|
||||
SortedMap<File, List<File>> map = new TreeMap<File, List<File>>();
|
||||
|
||||
|
||||
for (File file : files) {
|
||||
File key = file.getParentFile();
|
||||
if (key == null) {
|
||||
throw new IllegalArgumentException("Parent is null: " + file);
|
||||
}
|
||||
|
||||
|
||||
List<File> valueList = map.get(key);
|
||||
if (valueList == null) {
|
||||
valueList = new ArrayList<File>();
|
||||
map.put(key, valueList);
|
||||
}
|
||||
|
||||
|
||||
valueList.add(file);
|
||||
}
|
||||
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static Map<String, List<File>> mapByExtension(Iterable<File> files) {
|
||||
Map<String, List<File>> map = new HashMap<String, List<File>>();
|
||||
|
||||
|
||||
for (File file : files) {
|
||||
String key = getExtension(file);
|
||||
if (key != null) {
|
||||
key = key.toLowerCase();
|
||||
}
|
||||
|
||||
|
||||
List<File> valueList = map.get(key);
|
||||
if (valueList == null) {
|
||||
valueList = new ArrayList<File>();
|
||||
map.put(key, valueList);
|
||||
}
|
||||
|
||||
|
||||
valueList.add(file);
|
||||
}
|
||||
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Invalid file name characters: \, /, :, *, ?, ", <, >, |, \r and \n
|
||||
*/
|
||||
public static final Pattern ILLEGAL_CHARACTERS = Pattern.compile("[\\\\/:*?\"<>|\\r\\n]|[. ]+$");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Strip file name of invalid characters
|
||||
*
|
||||
* @param filename original filename
|
||||
* @param filename
|
||||
* original filename
|
||||
* @return valid file name stripped of invalid characters
|
||||
*/
|
||||
public static String validateFileName(CharSequence filename) {
|
||||
// strip invalid characters from file name
|
||||
return ILLEGAL_CHARACTERS.matcher(filename).replaceAll("").trim();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static boolean isInvalidFileName(CharSequence filename) {
|
||||
// check if file name contains any illegal characters
|
||||
return ILLEGAL_CHARACTERS.matcher(filename).find();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static File validateFileName(File file) {
|
||||
// windows drives (e.g. c:, d:, etc.) are never invalid because name will be an empty string
|
||||
if (!isInvalidFileName(file.getName()))
|
||||
return file;
|
||||
|
||||
|
||||
// validate file name only
|
||||
return new File(file.getParentFile(), validateFileName(file.getName()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static File validateFilePath(File path) {
|
||||
Iterator<File> nodes = listPath(path).iterator();
|
||||
|
||||
|
||||
// initialize with root node, keep original root object if possible (so we don't loose the drive on windows)
|
||||
File validatedPath = validateFileName(nodes.next());
|
||||
|
||||
|
||||
// validate the rest of the path
|
||||
while (nodes.hasNext()) {
|
||||
validatedPath = new File(validatedPath, validateFileName(nodes.next().getName()));
|
||||
}
|
||||
|
||||
|
||||
return validatedPath;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static boolean isInvalidFilePath(File path) {
|
||||
// check if file name contains any illegal characters
|
||||
for (File node = path; node != null; node = node.getParentFile()) {
|
||||
if (isInvalidFileName(node.getName()))
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static String normalizePathSeparators(String path) {
|
||||
// special handling for UNC paths
|
||||
if (path.startsWith(UNC_PREFIX) && path.length() > 2) {
|
||||
@ -522,34 +497,30 @@ public final class FileUtilities {
|
||||
}
|
||||
return path.replace('\\', '/');
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static String replacePathSeparators(CharSequence path) {
|
||||
return replacePathSeparators(path, " ");
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static String replacePathSeparators(CharSequence path, String replacement) {
|
||||
return Pattern.compile("\\s*[\\\\/]+\\s*").matcher(path).replaceAll(replacement);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static String getXmlString(Document dom) throws TransformerException {
|
||||
Transformer tr = TransformerFactory.newInstance().newTransformer();
|
||||
tr.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
|
||||
tr.setOutputProperty(OutputKeys.INDENT, "yes");
|
||||
|
||||
|
||||
// create string from dom
|
||||
StringWriter buffer = new StringWriter();
|
||||
tr.transform(new DOMSource(dom), new StreamResult(buffer));
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
|
||||
public static final long KILO = 1024;
|
||||
public static final long MEGA = KILO * 1024;
|
||||
public static final long GIGA = MEGA * 1024;
|
||||
|
||||
|
||||
|
||||
public static String formatSize(long size) {
|
||||
if (size >= MEGA)
|
||||
return String.format("%,d MB", size / MEGA);
|
||||
@ -558,121 +529,105 @@ public final class FileUtilities {
|
||||
else
|
||||
return String.format("%,d Byte", size);
|
||||
}
|
||||
|
||||
|
||||
public static final FileFilter FOLDERS = new FileFilter() {
|
||||
|
||||
|
||||
@Override
|
||||
public boolean accept(File file) {
|
||||
return file.isDirectory();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
public static final FileFilter FILES = new FileFilter() {
|
||||
|
||||
|
||||
@Override
|
||||
public boolean accept(File file) {
|
||||
return file.isFile();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
public static final FileFilter TEMPORARY = new FileFilter() {
|
||||
|
||||
|
||||
private final String tmpdir = System.getProperty("java.io.tmpdir");
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean accept(File file) {
|
||||
return file.getAbsolutePath().startsWith(tmpdir);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
public static class ParentFilter implements FileFilter {
|
||||
|
||||
|
||||
private final File folder;
|
||||
|
||||
|
||||
|
||||
public ParentFilter(File folder) {
|
||||
this.folder = folder;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean accept(File file) {
|
||||
return listPath(file).contains(folder);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static class ExtensionFileFilter implements FileFilter {
|
||||
|
||||
|
||||
private final String[] extensions;
|
||||
|
||||
|
||||
|
||||
public ExtensionFileFilter(String... extensions) {
|
||||
this.extensions = extensions;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public ExtensionFileFilter(Collection<String> extensions) {
|
||||
this.extensions = extensions.toArray(new String[0]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean accept(File file) {
|
||||
return hasExtension(file, extensions);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public boolean accept(String name) {
|
||||
return hasExtension(name, extensions);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public boolean acceptExtension(String extension) {
|
||||
for (String other : extensions) {
|
||||
if (other.equalsIgnoreCase(extension))
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public String extension() {
|
||||
return extensions[0];
|
||||
}
|
||||
|
||||
|
||||
|
||||
public String[] extensions() {
|
||||
return extensions.clone();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static class NotFileFilter implements FileFilter {
|
||||
|
||||
|
||||
public FileFilter filter;
|
||||
|
||||
|
||||
|
||||
public NotFileFilter(FileFilter filter) {
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean accept(File file) {
|
||||
return !filter.accept(file);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Dummy constructor to prevent instantiation.
|
||||
*/
|
||||
private FileUtilities() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user