mirror of
https://github.com/mitb-archive/filebot
synced 2024-12-22 15:58:52 -05:00
* dnd move: cancel background threads when calling BackgroundFileTransferablePolicy.clear()
* added FastFile, which minimizes fs calls by remembering the results * use File directly (and not the holder FileEntry) in RenamePanel
This commit is contained in:
parent
5733cfbcdc
commit
9d7af8bd96
@ -2,6 +2,7 @@
|
||||
package net.sourceforge.filebot.similarity;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
@ -35,8 +36,13 @@ public class SeasonEpisodeSimilarityMetric implements SimilarityMetric {
|
||||
}
|
||||
|
||||
|
||||
protected Collection<SxE> parse(Object o) {
|
||||
return seasonEpisodeMatcher.match(o.toString());
|
||||
protected Collection<SxE> parse(Object object) {
|
||||
if (object instanceof File) {
|
||||
// parse file name
|
||||
object = ((File) object).getName();
|
||||
}
|
||||
|
||||
return seasonEpisodeMatcher.match(object.toString());
|
||||
}
|
||||
|
||||
|
||||
|
@ -178,7 +178,7 @@ public class Torrent {
|
||||
public static class Entry {
|
||||
|
||||
private final String name;
|
||||
private final Long length;
|
||||
private final long length;
|
||||
private final String path;
|
||||
|
||||
|
||||
@ -194,7 +194,7 @@ public class Torrent {
|
||||
}
|
||||
|
||||
|
||||
public Long getLength() {
|
||||
public long getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@ import net.sourceforge.filebot.ui.panel.analyze.FileTree.FileNode;
|
||||
import net.sourceforge.filebot.ui.panel.analyze.FileTree.FolderNode;
|
||||
import net.sourceforge.filebot.ui.transfer.BackgroundFileTransferablePolicy;
|
||||
import net.sourceforge.tuned.ExceptionUtilities;
|
||||
import net.sourceforge.tuned.FastFile;
|
||||
import net.sourceforge.tuned.FileUtilities;
|
||||
|
||||
|
||||
@ -33,6 +34,8 @@ class FileTreeTransferablePolicy extends BackgroundFileTransferablePolicy<Abstra
|
||||
|
||||
@Override
|
||||
protected void clear() {
|
||||
super.clear();
|
||||
|
||||
tree.clear();
|
||||
}
|
||||
|
||||
@ -59,7 +62,7 @@ class FileTreeTransferablePolicy extends BackgroundFileTransferablePolicy<Abstra
|
||||
protected void load(List<File> files) {
|
||||
try {
|
||||
for (File file : files) {
|
||||
AbstractTreeNode node = getTreeNode(file);
|
||||
AbstractTreeNode node = getTreeNode(new FastFile(file.getPath()));
|
||||
|
||||
// publish on EDT
|
||||
publish(node);
|
||||
|
@ -1,33 +0,0 @@
|
||||
|
||||
package net.sourceforge.filebot.ui.panel.rename;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import net.sourceforge.tuned.FileUtilities;
|
||||
|
||||
|
||||
class FileEntry extends AbstractFileEntry {
|
||||
|
||||
private final File file;
|
||||
private final String type;
|
||||
|
||||
|
||||
public FileEntry(File file) {
|
||||
super(FileUtilities.getName(file), file.length());
|
||||
|
||||
this.file = file;
|
||||
this.type = FileUtilities.getType(file);
|
||||
}
|
||||
|
||||
|
||||
public File getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
}
|
@ -10,14 +10,15 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import net.sourceforge.filebot.ui.transfer.FileTransferablePolicy;
|
||||
import net.sourceforge.tuned.FastFile;
|
||||
|
||||
|
||||
class FilesListTransferablePolicy extends FileTransferablePolicy {
|
||||
|
||||
private final List<? super FileEntry> model;
|
||||
private final List<File> model;
|
||||
|
||||
|
||||
public FilesListTransferablePolicy(List<? super FileEntry> model) {
|
||||
public FilesListTransferablePolicy(List<File> model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
@ -48,7 +49,7 @@ class FilesListTransferablePolicy extends FileTransferablePolicy {
|
||||
|
||||
protected void loadFiles(List<File> files) {
|
||||
for (File file : files) {
|
||||
model.add(new FileEntry(file));
|
||||
model.add(new FastFile(file.getPath()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@ import java.awt.Cursor;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
@ -30,6 +31,7 @@ import net.sourceforge.filebot.similarity.SeasonEpisodeSimilarityMetric;
|
||||
import net.sourceforge.filebot.similarity.SimilarityMetric;
|
||||
import net.sourceforge.filebot.similarity.SeasonEpisodeMatcher.SxE;
|
||||
import net.sourceforge.filebot.web.Episode;
|
||||
import net.sourceforge.tuned.FileUtilities;
|
||||
import net.sourceforge.tuned.ui.ProgressDialog;
|
||||
import net.sourceforge.tuned.ui.SwingWorkerPropertyChangeAdapter;
|
||||
import net.sourceforge.tuned.ui.ProgressDialog.Cancellable;
|
||||
@ -59,12 +61,12 @@ class MatchAction extends AbstractAction {
|
||||
metrics[0] = new LengthEqualsMetric() {
|
||||
|
||||
@Override
|
||||
protected long getLength(Object o) {
|
||||
if (o instanceof AbstractFileEntry) {
|
||||
return ((AbstractFileEntry) o).getLength();
|
||||
protected long getLength(Object object) {
|
||||
if (object instanceof AbstractFileEntry) {
|
||||
return ((AbstractFileEntry) object).getLength();
|
||||
}
|
||||
|
||||
return super.getLength(o);
|
||||
return super.getLength(object);
|
||||
}
|
||||
};
|
||||
|
||||
@ -90,7 +92,18 @@ class MatchAction extends AbstractAction {
|
||||
};
|
||||
|
||||
// 3. pass: match by generic name similarity (slow, but most matches will have been determined in second pass)
|
||||
metrics[2] = new NameSimilarityMetric();
|
||||
metrics[2] = new NameSimilarityMetric() {
|
||||
|
||||
@Override
|
||||
protected String normalize(Object object) {
|
||||
if (object instanceof File) {
|
||||
// compare to filename without extension
|
||||
object = FileUtilities.getName((File) object);
|
||||
}
|
||||
|
||||
return super.normalize(object);
|
||||
}
|
||||
};
|
||||
|
||||
return Arrays.asList(metrics);
|
||||
}
|
||||
@ -151,19 +164,19 @@ class MatchAction extends AbstractAction {
|
||||
}
|
||||
|
||||
|
||||
protected class BackgroundMatcher extends SwingWorker<List<Match<Object, FileEntry>>, Void> implements Cancellable {
|
||||
protected class BackgroundMatcher extends SwingWorker<List<Match<Object, File>>, Void> implements Cancellable {
|
||||
|
||||
private final Matcher<Object, FileEntry> matcher;
|
||||
private final Matcher<Object, File> matcher;
|
||||
|
||||
|
||||
public BackgroundMatcher(RenameModel model, Collection<SimilarityMetric> metrics) {
|
||||
// match names against files
|
||||
this.matcher = new Matcher<Object, FileEntry>(model.names(), model.files(), metrics);
|
||||
this.matcher = new Matcher<Object, File>(model.names(), model.files(), metrics);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected List<Match<Object, FileEntry>> doInBackground() throws Exception {
|
||||
protected List<Match<Object, File>> doInBackground() throws Exception {
|
||||
return matcher.match();
|
||||
}
|
||||
|
||||
@ -174,12 +187,12 @@ class MatchAction extends AbstractAction {
|
||||
return;
|
||||
|
||||
try {
|
||||
List<Match<Object, FileEntry>> matches = get();
|
||||
List<Match<Object, File>> matches = get();
|
||||
|
||||
model.clear();
|
||||
|
||||
// put new data into model
|
||||
for (Match<Object, FileEntry> match : matches) {
|
||||
for (Match<Object, File> match : matches) {
|
||||
model.names().add(match.getValue());
|
||||
model.files().add(match.getCandidate());
|
||||
}
|
||||
|
@ -2,29 +2,24 @@
|
||||
package net.sourceforge.filebot.ui.panel.rename;
|
||||
|
||||
|
||||
class StringEntry {
|
||||
class MutableString {
|
||||
|
||||
private String value;
|
||||
|
||||
|
||||
public StringEntry(Object value) {
|
||||
setValue(value);
|
||||
public MutableString(Object value) {
|
||||
set(value);
|
||||
}
|
||||
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
public void setValue(Object value) {
|
||||
public void set(Object value) {
|
||||
this.value = String.valueOf(value);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getValue();
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
@ -80,12 +80,13 @@ class NamesListTransferablePolicy extends FileTransferablePolicy {
|
||||
}
|
||||
|
||||
|
||||
protected void submit(List<StringEntry> entries) {
|
||||
List<StringEntry> invalidEntries = new ArrayList<StringEntry>();
|
||||
protected void submit(List<MutableString> entries) {
|
||||
List<MutableString> invalidEntries = new ArrayList<MutableString>();
|
||||
|
||||
for (StringEntry entry : entries) {
|
||||
if (isInvalidFileName(entry.getValue()))
|
||||
for (MutableString entry : entries) {
|
||||
if (isInvalidFileName(entry.toString())) {
|
||||
invalidEntries.add(entry);
|
||||
}
|
||||
}
|
||||
|
||||
if (!invalidEntries.isEmpty()) {
|
||||
@ -103,7 +104,7 @@ class NamesListTransferablePolicy extends FileTransferablePolicy {
|
||||
|
||||
|
||||
protected void load(String string) {
|
||||
List<StringEntry> entries = new ArrayList<StringEntry>();
|
||||
List<MutableString> entries = new ArrayList<MutableString>();
|
||||
|
||||
Scanner scanner = new Scanner(string).useDelimiter(LINE_SEPARATOR);
|
||||
|
||||
@ -111,7 +112,7 @@ class NamesListTransferablePolicy extends FileTransferablePolicy {
|
||||
String line = scanner.next();
|
||||
|
||||
if (line.trim().length() > 0) {
|
||||
entries.add(new StringEntry(line));
|
||||
entries.add(new MutableString(line));
|
||||
}
|
||||
}
|
||||
|
||||
@ -145,7 +146,7 @@ class NamesListTransferablePolicy extends FileTransferablePolicy {
|
||||
|
||||
protected void loadListFiles(List<File> files) {
|
||||
try {
|
||||
List<StringEntry> entries = new ArrayList<StringEntry>();
|
||||
List<MutableString> entries = new ArrayList<MutableString>();
|
||||
|
||||
for (File file : files) {
|
||||
Scanner scanner = new Scanner(file, "UTF-8").useDelimiter(LINE_SEPARATOR);
|
||||
@ -154,7 +155,7 @@ class NamesListTransferablePolicy extends FileTransferablePolicy {
|
||||
String line = scanner.next();
|
||||
|
||||
if (line.trim().length() > 0) {
|
||||
entries.add(new StringEntry(line));
|
||||
entries.add(new MutableString(line));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,19 +36,18 @@ class RenameAction extends AbstractAction {
|
||||
Deque<Match<File, File>> todoQueue = new ArrayDeque<Match<File, File>>();
|
||||
Deque<Match<File, File>> doneQueue = new ArrayDeque<Match<File, File>>();
|
||||
|
||||
for (Match<Object, FileEntry> match : model.matches()) {
|
||||
File source = match.getCandidate().getFile();
|
||||
|
||||
for (Match<Object, File> match : model.matches()) {
|
||||
File source = match.getCandidate();
|
||||
String extension = FileUtilities.getExtension(source);
|
||||
|
||||
StringBuilder nameBuilder = new StringBuilder();
|
||||
nameBuilder.append(match.getValue());
|
||||
StringBuilder name = new StringBuilder();
|
||||
name.append(match.getValue());
|
||||
|
||||
if (extension != null) {
|
||||
nameBuilder.append(".").append(extension);
|
||||
name.append(".").append(extension);
|
||||
}
|
||||
|
||||
File target = new File(source.getParentFile(), nameBuilder.toString());
|
||||
File target = new File(source.getParentFile(), name.toString());
|
||||
|
||||
todoQueue.addLast(new Match<File, File>(source, target));
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import java.awt.Insets;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
import java.io.File;
|
||||
|
||||
import javax.swing.Box;
|
||||
import javax.swing.BoxLayout;
|
||||
@ -18,6 +19,7 @@ import javax.swing.JList;
|
||||
import javax.swing.border.CompoundBorder;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
|
||||
import net.sourceforge.tuned.FileUtilities;
|
||||
import net.sourceforge.tuned.ui.DefaultFancyListCellRenderer;
|
||||
|
||||
|
||||
@ -47,17 +49,19 @@ class RenameListCellRenderer extends DefaultFancyListCellRenderer {
|
||||
super.configureListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
|
||||
|
||||
// show extension label only for items of the files model
|
||||
if (value instanceof FileEntry) {
|
||||
FileEntry entry = (FileEntry) value;
|
||||
if (value instanceof File) {
|
||||
File file = (File) value;
|
||||
|
||||
this.setText(FileUtilities.getName(file));
|
||||
|
||||
extension.setText(getType(file));
|
||||
extension.setAlpha(1.0f);
|
||||
|
||||
extension.setText(entry.getType());
|
||||
extension.setVisible(true);
|
||||
} else {
|
||||
extension.setVisible(false);
|
||||
}
|
||||
|
||||
extension.setAlpha(1.0f);
|
||||
|
||||
if (index >= model.matchCount()) {
|
||||
if (isSelected) {
|
||||
setGradientColors(noMatchGradientBeginColor, noMatchGradientEndColor);
|
||||
@ -68,6 +72,20 @@ class RenameListCellRenderer extends DefaultFancyListCellRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected String getType(File file) {
|
||||
if (file.isDirectory())
|
||||
return "Folder";
|
||||
|
||||
String extension = FileUtilities.getExtension(file);
|
||||
|
||||
if (!extension.isEmpty())
|
||||
return extension;
|
||||
|
||||
// some file with no extension
|
||||
return "File";
|
||||
}
|
||||
|
||||
|
||||
protected class ExtensionLabel extends JLabel {
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
package net.sourceforge.filebot.ui.panel.rename;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.util.AbstractList;
|
||||
import java.util.Collection;
|
||||
|
||||
@ -13,7 +14,7 @@ import ca.odell.glazedlists.EventList;
|
||||
class RenameModel {
|
||||
|
||||
private final EventList<Object> names = new BasicEventList<Object>();
|
||||
private final EventList<FileEntry> files = new BasicEventList<FileEntry>();
|
||||
private final EventList<File> files = new BasicEventList<File>();
|
||||
|
||||
|
||||
public EventList<Object> names() {
|
||||
@ -21,7 +22,7 @@ class RenameModel {
|
||||
}
|
||||
|
||||
|
||||
public EventList<FileEntry> files() {
|
||||
public EventList<File> files() {
|
||||
return files;
|
||||
}
|
||||
|
||||
@ -37,19 +38,19 @@ class RenameModel {
|
||||
}
|
||||
|
||||
|
||||
public Match<Object, FileEntry> getMatch(int index) {
|
||||
public Match<Object, File> getMatch(int index) {
|
||||
if (index >= matchCount())
|
||||
throw new IndexOutOfBoundsException();
|
||||
|
||||
return new Match<Object, FileEntry>(names.get(index), files.get(index));
|
||||
return new Match<Object, File>(names.get(index), files.get(index));
|
||||
}
|
||||
|
||||
|
||||
public Collection<Match<Object, FileEntry>> matches() {
|
||||
return new AbstractList<Match<Object, FileEntry>>() {
|
||||
public Collection<Match<Object, File>> matches() {
|
||||
return new AbstractList<Match<Object, File>>() {
|
||||
|
||||
@Override
|
||||
public Match<Object, FileEntry> get(int index) {
|
||||
public Match<Object, File> get(int index) {
|
||||
return getMatch(index);
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,7 @@ public class RenamePanel extends FileBotPanel {
|
||||
|
||||
private RenameList<Object> namesList = new RenameList<Object>(model.names());
|
||||
|
||||
private RenameList<FileEntry> filesList = new RenameList<FileEntry>(model.files());
|
||||
private RenameList<File> filesList = new RenameList<File>(model.files());
|
||||
|
||||
private MatchAction matchAction = new MatchAction(model);
|
||||
|
||||
@ -111,7 +111,7 @@ public class RenamePanel extends FileBotPanel {
|
||||
|
||||
// repaint on change
|
||||
model.names().addListEventListener(new RepaintHandler<Object>());
|
||||
model.files().addListEventListener(new RepaintHandler<FileEntry>());
|
||||
model.files().addListEventListener(new RepaintHandler<File>());
|
||||
}
|
||||
|
||||
protected final Action showPopupAction = new AbstractAction("Show Popup") {
|
||||
@ -164,14 +164,7 @@ public class RenamePanel extends FileBotPanel {
|
||||
// clear names list
|
||||
model.names().clear();
|
||||
|
||||
// gather File objects from model
|
||||
List<File> files = new ArrayList<File>();
|
||||
|
||||
for (FileEntry entry : model.files()) {
|
||||
files.add(entry.getFile());
|
||||
}
|
||||
|
||||
AutoFetchEpisodeListMatcher worker = new AutoFetchEpisodeListMatcher(client, files, matchAction.getMetrics()) {
|
||||
AutoFetchEpisodeListMatcher worker = new AutoFetchEpisodeListMatcher(client, model.files(), matchAction.getMetrics()) {
|
||||
|
||||
@Override
|
||||
protected void done() {
|
||||
@ -179,20 +172,20 @@ public class RenamePanel extends FileBotPanel {
|
||||
setAutoMatchInProgress(false);
|
||||
|
||||
try {
|
||||
List<StringEntry> names = new ArrayList<StringEntry>();
|
||||
List<FileEntry> files = new ArrayList<FileEntry>();
|
||||
List<MutableString> names = new ArrayList<MutableString>();
|
||||
List<File> files = new ArrayList<File>();
|
||||
|
||||
List<StringEntry> invalidNames = new ArrayList<StringEntry>();
|
||||
List<MutableString> invalidNames = new ArrayList<MutableString>();
|
||||
|
||||
for (Match<File, Episode> match : get()) {
|
||||
StringEntry name = new StringEntry(match.getCandidate());
|
||||
MutableString name = new MutableString(match.getCandidate());
|
||||
|
||||
if (isInvalidFileName(name.toString())) {
|
||||
invalidNames.add(name);
|
||||
}
|
||||
|
||||
names.add(name);
|
||||
files.add(new FileEntry(match.getValue()));
|
||||
files.add(match.getValue());
|
||||
}
|
||||
|
||||
if (!invalidNames.isEmpty()) {
|
||||
@ -205,15 +198,13 @@ public class RenamePanel extends FileBotPanel {
|
||||
}
|
||||
}
|
||||
|
||||
// add remaining file entries
|
||||
for (File file : remainingFiles()) {
|
||||
files.add(new FileEntry(file));
|
||||
}
|
||||
|
||||
model.clear();
|
||||
|
||||
model.names().addAll(names);
|
||||
model.files().addAll(files);
|
||||
|
||||
// add remaining file entries
|
||||
model.files().addAll(remainingFiles());
|
||||
} catch (Exception e) {
|
||||
Logger.getLogger("ui").log(Level.WARNING, ExceptionUtilities.getRootCauseMessage(e), e);
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ import net.sourceforge.tuned.ui.TunedUtilities;
|
||||
|
||||
class ValidateNamesDialog extends JDialog {
|
||||
|
||||
private final Collection<StringEntry> entries;
|
||||
private final Collection<MutableString> entries;
|
||||
|
||||
private boolean cancelled = true;
|
||||
|
||||
@ -40,7 +40,7 @@ class ValidateNamesDialog extends JDialog {
|
||||
protected final Action cancelAction = new CancelAction();
|
||||
|
||||
|
||||
public ValidateNamesDialog(Window owner, Collection<StringEntry> entries) {
|
||||
public ValidateNamesDialog(Window owner, Collection<MutableString> entries) {
|
||||
super(owner, "Invalid Names", ModalityType.DOCUMENT_MODAL);
|
||||
|
||||
this.entries = entries;
|
||||
@ -94,8 +94,8 @@ class ValidateNamesDialog extends JDialog {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
for (StringEntry entry : entries) {
|
||||
entry.setValue(validateFileName(entry.getValue()));
|
||||
for (MutableString entry : entries) {
|
||||
entry.set(validateFileName(entry.toString()));
|
||||
}
|
||||
|
||||
setEnabled(false);
|
||||
|
@ -41,13 +41,22 @@ public abstract class BackgroundFileTransferablePolicy<V> extends FileTransferab
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void clear() {
|
||||
// stop other workers on clear (before starting new worker)
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
public void reset() {
|
||||
synchronized (workers) {
|
||||
for (BackgroundWorker worker : workers) {
|
||||
worker.cancel(true);
|
||||
if (workers.size() > 0) {
|
||||
// avoid ConcurrentModificationException by iterating over a copy
|
||||
for (BackgroundWorker worker : new ArrayList<BackgroundWorker>(workers)) {
|
||||
// worker.cancel() will invoke worker.done() which will invoke workers.remove(worker)
|
||||
worker.cancel(true);
|
||||
}
|
||||
}
|
||||
|
||||
workers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@ -70,6 +79,7 @@ public abstract class BackgroundFileTransferablePolicy<V> extends FileTransferab
|
||||
|
||||
public BackgroundWorker(List<File> files) {
|
||||
this.files = files;
|
||||
|
||||
// register this worker
|
||||
synchronized (workers) {
|
||||
if (workers.add(this) && workers.size() == 1) {
|
||||
|
55
source/net/sourceforge/tuned/FastFile.java
Normal file
55
source/net/sourceforge/tuned/FastFile.java
Normal file
@ -0,0 +1,55 @@
|
||||
|
||||
package net.sourceforge.tuned;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
|
||||
|
||||
public class FastFile extends File {
|
||||
|
||||
private Long length;
|
||||
private Boolean isDirectory;
|
||||
private Boolean isFile;
|
||||
|
||||
|
||||
public FastFile(String path) {
|
||||
super(path);
|
||||
}
|
||||
|
||||
|
||||
public FastFile(File parent, String child) {
|
||||
super(parent, child);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public long length() {
|
||||
return length != null ? length : (length = super.length());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isDirectory() {
|
||||
return isDirectory != null ? isDirectory : (isDirectory = super.isDirectory());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isFile() {
|
||||
return isFile != null ? isFile : (isFile = super.isFile());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public File[] listFiles() {
|
||||
String[] names = list();
|
||||
File[] files = new File[names.length];
|
||||
|
||||
for (int i = 0; i < names.length; i++) {
|
||||
files[i] = new FastFile(this, names[i]);
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
}
|
@ -94,20 +94,6 @@ public final class FileUtilities {
|
||||
}
|
||||
|
||||
|
||||
public static String getType(File file) {
|
||||
if (file.isDirectory())
|
||||
return "Folder";
|
||||
|
||||
String extension = getExtension(file.getName());
|
||||
|
||||
if (!extension.isEmpty())
|
||||
return extension;
|
||||
|
||||
// some file with no extension
|
||||
return "File";
|
||||
}
|
||||
|
||||
|
||||
public static boolean containsOnly(Iterable<File> files, FileFilter filter) {
|
||||
for (File file : files) {
|
||||
if (!filter.accept(file))
|
||||
|
Loading…
Reference in New Issue
Block a user