Refactor trash/delete

This commit is contained in:
Reinhard Pointner 2016-05-16 03:09:30 +08:00
parent d886f6569f
commit 5244a33fac
6 changed files with 71 additions and 38 deletions

View File

@ -58,8 +58,10 @@ public class CacheManager {
private void clearDiskStore(File cache) { private void clearDiskStore(File cache) {
getChildren(cache).stream().filter(f -> f.isFile() && !f.getName().startsWith(".")).forEach(f -> { getChildren(cache).stream().filter(f -> f.isFile() && !f.getName().startsWith(".")).forEach(f -> {
if (!delete(f)) { try {
debug.warning(format("Failed to delete cache: %s", f.getName())); delete(f);
} catch (Exception e) {
debug.warning(format("Failed to delete cache: %s => %s", f, e));
} }
}); });
} }

View File

@ -86,11 +86,8 @@ public class Main {
if (args.clearCache()) { if (args.clearCache()) {
System.out.println("Clear cache"); System.out.println("Clear cache");
for (File folder : getChildren(ApplicationFolder.Cache.getCanonicalFile(), FOLDERS)) { for (File folder : getChildren(ApplicationFolder.Cache.getCanonicalFile(), FOLDERS)) {
if (delete(folder)) { System.out.println("Delete " + folder);
System.out.println("* Delete " + folder); delete(folder);
} else {
System.out.println("* Failed to delete " + folder);
}
} }
} }

View File

@ -1,9 +1,11 @@
package net.filebot; package net.filebot;
import static java.util.Collections.*; import static java.util.Collections.*;
import static net.filebot.Logging.*;
import static net.filebot.util.FileUtilities.*; import static net.filebot.util.FileUtilities.*;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.concurrent.CancellationException; import java.util.concurrent.CancellationException;
@ -64,4 +66,27 @@ public enum NativeRenameAction implements RenameAction {
} }
} }
public static void trash(File file) throws IOException {
// use system trash if possible
try {
if (Platform.isMac()) {
// use com.apple.eio package on OS X platform
if (com.apple.eio.FileManager.moveToTrash(file)) {
return;
}
} else if (com.sun.jna.platform.FileUtils.getInstance().hasTrash()) {
// use com.sun.jna.platform package on Windows and Linux
com.sun.jna.platform.FileUtils.getInstance().moveToTrash(new File[] { file });
return;
}
} catch (Exception e) {
debug.warning(e::toString);
}
// delete permanently if necessary
if (file.exists()) {
net.filebot.util.FileUtilities.delete(file);
}
}
} }

View File

@ -149,29 +149,29 @@ public enum StandardRenameAction implements RenameAction {
// reverse symlink // reverse symlink
if (currentAttr.isSymbolicLink() && !originalAttr.isSymbolicLink()) { if (currentAttr.isSymbolicLink() && !originalAttr.isSymbolicLink()) {
Files.delete(current.toPath()); NativeRenameAction.trash(current);
return original; return original;
} }
// reverse keeplink // reverse keeplink
if (!currentAttr.isSymbolicLink() && originalAttr.isSymbolicLink()) { if (!currentAttr.isSymbolicLink() && originalAttr.isSymbolicLink()) {
Files.delete(original.toPath()); NativeRenameAction.trash(original);
return FileUtilities.moveRename(current, original); return FileUtilities.moveRename(current, original);
} }
// reverse copy / hardlink // reverse copy / hardlink
if (currentAttr.isRegularFile() && originalAttr.isRegularFile()) { if (currentAttr.isRegularFile() && originalAttr.isRegularFile()) {
Files.delete(current.toPath()); NativeRenameAction.trash(current);
return original; return original;
} }
// reverse folder copy // reverse folder copy
if (currentAttr.isDirectory() && originalAttr.isDirectory()) { if (currentAttr.isDirectory() && originalAttr.isDirectory()) {
FileUtilities.delete(original); NativeRenameAction.trash(original);
return FileUtilities.moveRename(current, original); return FileUtilities.moveRename(current, original);
} }
throw new IllegalArgumentException(String.format("Cannot revert files: %s => %s", current, original)); throw new IllegalArgumentException(String.format("Cannot revert file: %s => %s", current, original));
} }
} }

View File

@ -19,7 +19,6 @@ import java.io.IOException;
import java.util.AbstractList; import java.util.AbstractList;
import java.util.AbstractMap.SimpleEntry; import java.util.AbstractMap.SimpleEntry;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
@ -41,8 +40,6 @@ import javax.swing.JList;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import javax.swing.JScrollPane; import javax.swing.JScrollPane;
import com.sun.jna.platform.FileUtils;
import net.filebot.HistorySpooler; import net.filebot.HistorySpooler;
import net.filebot.NativeRenameAction; import net.filebot.NativeRenameAction;
import net.filebot.ResourceManager; import net.filebot.ResourceManager;
@ -153,7 +150,7 @@ class RenameAction extends AbstractAction {
private void deleteEmptyFolders(Map<File, File> renameMap) { private void deleteEmptyFolders(Map<File, File> renameMap) {
// collect empty folders and files in reverse order // collect empty folders and files in reverse order
Set<File> empty = new TreeSet<File>(); Set<File> deleteFiles = new TreeSet<File>();
renameMap.forEach((s, d) -> { renameMap.forEach((s, d) -> {
File sourceFolder = s.getParentFile(); File sourceFolder = s.getParentFile();
@ -170,12 +167,12 @@ class RenameAction extends AbstractAction {
for (int i = 0; i < tailSize && !isStructureRoot(sourceFolder); sourceFolder = sourceFolder.getParentFile(), i++) { for (int i = 0; i < tailSize && !isStructureRoot(sourceFolder); sourceFolder = sourceFolder.getParentFile(), i++) {
File[] children = sourceFolder.listFiles(); File[] children = sourceFolder.listFiles();
if (children == null || !stream(children).allMatch(f -> empty.contains(f) || isThumbnailStore(f))) { if (children == null || !stream(children).allMatch(f -> deleteFiles.contains(f) || isThumbnailStore(f))) {
return; return;
} }
stream(children).forEach(empty::add); stream(children).forEach(deleteFiles::add);
empty.add(sourceFolder); deleteFiles.add(sourceFolder);
} }
} catch (Exception e) { } catch (Exception e) {
debug.warning(e::toString); debug.warning(e::toString);
@ -183,22 +180,10 @@ class RenameAction extends AbstractAction {
}); });
// use system trash to delete left-behind empty folders / hidden files // use system trash to delete left-behind empty folders / hidden files
moveToTrash(empty);
}
protected void moveToTrash(Collection<File> files) {
try { try {
for (File f : files) { for (File file : deleteFiles) {
if (!f.exists()) { if (file.exists()) {
continue; NativeRenameAction.trash(file);
}
if (isMacApp()) {
// use com.apple.eio package on OS X platform
MacAppUtilities.moveToTrash(f);
} else {
// use com.sun.jna.platform package on Windows and Linux
FileUtils.getInstance().moveToTrash(new File[] { f });
} }
} }
} catch (Throwable e) { } catch (Throwable e) {

View File

@ -67,7 +67,7 @@ public final class FileUtilities {
// on Windows, use ATOMIC_MOVE which allows us to rename files even if only lower/upper-case changes (without ATOMIC_MOVE the operation would be ignored) // on Windows, use ATOMIC_MOVE which allows us to rename files even if only lower/upper-case changes (without ATOMIC_MOVE the operation would be ignored)
// but ATOMIC_MOVE can only work for files on the same drive, if that is not the case there is no point trying move with ATOMIC_MOVE // but ATOMIC_MOVE can only work for files on the same drive, if that is not the case there is no point trying move with ATOMIC_MOVE
if (File.separator.equals("\\") && source.equals(destination)) { if (isWindows() && source.equals(destination) && !equalsCaseSensitive(source, destination)) {
try { try {
return Files.move(source.toPath(), destination.toPath(), StandardCopyOption.ATOMIC_MOVE).toFile(); return Files.move(source.toPath(), destination.toPath(), StandardCopyOption.ATOMIC_MOVE).toFile();
} catch (AtomicMoveNotSupportedException e) { } catch (AtomicMoveNotSupportedException e) {
@ -152,9 +152,25 @@ public final class FileUtilities {
return destination.toFile(); return destination.toFile();
} }
public static boolean delete(File file) { public static void delete(File file) throws IOException {
// delete files or files if (file.isDirectory()) {
return FileUtils.deleteQuietly(file); Files.walkFileTree(file.toPath(), new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path f, BasicFileAttributes attr) throws IOException {
Files.delete(f);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path f, IOException e) throws IOException {
Files.delete(f);
return FileVisitResult.CONTINUE;
}
});
} else {
Files.delete(file.toPath());
}
} }
public static File createFolders(File folder) throws IOException { public static File createFolders(File folder) throws IOException {
@ -225,6 +241,14 @@ public final class FileUtilities {
return UTF_8.decode(data).toString(); return UTF_8.decode(data).toString();
} }
public static boolean isWindows() {
return '\\' == File.separatorChar;
}
public static boolean equalsCaseSensitive(File a, File b) {
return a.getPath().equals(b.getPath());
}
/** /**
* Pattern used for matching file extensions. * Pattern used for matching file extensions.
* *