📄 duplicatechecker.java
字号:
/**
* DuMP3 version morpheus_0.2.9 - a duplicate/similar file finder in Java<BR>
* Copyright 2005 Alexander Grässer<BR>
* All Rights Reserved, http://dump3.sourceforge.net/<BR>
* <BR>
* This file is part of DuMP3.<BR>
* <BR>
* DuMP3 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 2 of the License, or (at your option) any later version.<BR>
* <BR>
* DuMP3 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.<BR>
* <BR>
* You should have received a copy of the GNU General Public License along with DuMP3; if not, write to the Free Software Foundation, Inc., 51 Franklin St,
* Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.za.grasser.duplicate;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Observable;
import java.util.Observer;
import java.util.SortedMap;
import java.util.TreeMap;
import net.za.grasser.duplicate.compare.Comparer;
import net.za.grasser.duplicate.file.DirectoryInfo;
import net.za.grasser.duplicate.file.DirectoryReader;
import net.za.grasser.duplicate.file.FingerprintFile;
import net.za.grasser.duplicate.persist.DatabaseFactory;
import net.za.grasser.duplicate.util.Constants;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
/**
* This class is the starting point of the command line checker.
*
* @modelguid {306AA9F8-1DA6-435D-89E7-9116B3F1AC91}
* @author <a href="http://sourceforge.net/sendmessage.php?touser=733840">pyropunk at sourceforge dot net</a>
* @version $Revision: 1.10 $
*/
public class DuplicateChecker implements Observer, Runnable {
/**
* <code>VERSION</code> DuplicateChecker -
*/
private static final String VERSION = "morpheus_0.2.9";
/** @modelguid {D4AF1AD2-EC0E-4C22-BC21-8C5DE9FFDBAC} */
static Logger log;
/**
* <code>running</code> DuplicateChecker -
*/
private boolean running = false;
/**
* <code>thread</code> DuplicateChecker -
*/
private Thread thread = null;
static {
Configure.load();
PropertyConfigurator.configure("./log4j.properties");
log = Logger.getLogger(DuplicateChecker.class);
}
/**
* Run as a command line application
*
* @param args
*/
private void runCommandLine(final String[] args) {
String[] dirs = null;
String wc = null;
if (args.length <= 0) {
dirs = new String[1];
dirs[0] = ".";
wc = "*";
} else {
if (args[args.length - 1].indexOf('*') >= 0 || args[args.length - 1].indexOf('?') >= 0 || args[args.length - 1].indexOf('[') >= 0) {
if (args.length == 1) {
dirs = new String[1];
dirs[0] = ".";
} else {
dirs = new String[args.length - 1];
for (int i = 0; i < dirs.length; i++) {
dirs[i] = args[i];
}
}
wc = args[args.length - 1];
} else {
dirs = new String[args.length];
for (int i = 0; i < dirs.length; i++) {
dirs[i] = args[i];
}
wc = "*";
}
}
if (wc.indexOf('[') == 0) {
wc = wc.substring(1);
}
if (wc.endsWith("]")) {
wc = wc.substring(0, wc.length() - 1);
}
final Comparer compare = Comparer.getInstance();
compare.addObserver(this);
compare.start();
log.debug("new Comparer created");
try {
for (final String element : dirs) {
log.debug("Wildcard:" + wc);
final DirectoryInfo df = new DirectoryInfo(element);
log.debug("new DirectoryInfo (" + element + ") created");
final DirectoryReader dr = new DirectoryReader(wc, df);
compare.addReader(dr);
log.debug("new DirectoryReader (" + wc + ", " + element + ") created");
dr.start();
log.debug("started");
}
} catch (final FileNotFoundException fnf) {
log.error("Error:", fnf);
setRunning(false);
}
}
/**
* This method prints usage info
*/
private void printUsage() {
log.info("Usage: java -cp <classpath> " + this.getClass().getName() + " [dir | file]... [\"[wildcard]\"]");
log.info("You must specify either a directory or a file or a wildcard.");
log.info("In windows enclose the wildcard in [] otherwise java will list the files in the current directory.");
}
/**
* DuplicateChecker constructor
*
* @param args
* @modelguid {0E8D1FB3-DAEF-4DF6-B52A-F7CE09641AC0}
*/
public DuplicateChecker(final String[] args) {
log.info("DuMP3 version " + VERSION);
Configure.load();
for (final String element : args) {
if (element.equalsIgnoreCase("-?") || element.startsWith("-h") || element.startsWith("--help")) {
printUsage();
return;
}
}
log.info("Press q<Enter> to stop.");
setRunning(true);
thread = new Thread(this, Constants.getClassName(this));
runCommandLine(args);
thread.start();
}
/**
* @param args String[]
* @modelguid {0460E075-7094-4781-AB83-DBC46C901CC0}
*/
public static void main(final String[] args) {
new DuplicateChecker(args);
}
/**
* list duplicates
*/
private void listDuplicates() {
final StringBuffer sb = new StringBuffer(100);
final Comparer compare = Comparer.getInstance();
log.warn("#duplicates: " + compare.getDuplicates().size());
log.warn("duplicate list:");
for (final FingerprintFile ff : compare.getDuplicates()) {
sb.append(Constants.LS).append(ff.toString());
// cut last LS
sb.setLength(sb.length() - Constants.LS.length());
log.warn(sb);
// clear
sb.setLength(0);
}
}
/**
* This method ...
*
* @param simList
* @param pfA
* @param pfB
*/
private void recursDuplicates(final SortedMap<Float, List<String>> simList, final FingerprintFile pfA, final FingerprintFile pfB) {
if (pfB != null && (pfA.getDuplicates() == null || pfA.getDuplicates().isEmpty())) {
final StringBuffer sb = new StringBuffer(100);
sb.setLength(0);
sb.append(pfB.getPath()).append(" =").append("(").append(pfA.getSimilarity()).append("%)").append("= ").append(pfA.getPath());
List<String> files = simList.get(new Float(pfA.getSimilarity()));
if (files == null) {
files = new ArrayList<String>();
simList.put(new Float(pfA.getSimilarity()), files);
}
files.add(sb.toString());
return;
}
for (final FingerprintFile ff : pfA.getDuplicates()) {
recursDuplicates(simList, ff, pfA);
}
}
/**
* sort dulicates by similarity
*/
private void listDuplicatesSorted() {
final Comparer compare = Comparer.getInstance();
log.warn("#duplicates: " + compare.getDuplicates().size());
log.warn("duplicate list sorted by similarity:");
final SortedMap<Float, List<String>> simList = new TreeMap<Float, List<String>>();
final Iterator<FingerprintFile> it = compare.getDuplicates().iterator();
while (it.hasNext()) {
recursDuplicates(simList, it.next(), null);
}
final Iterator<Float> it5 = simList.keySet().iterator();
while (it5.hasNext()) {
final Iterator<String> it2 = simList.get(it5.next()).iterator();
while (it2.hasNext()) {
log.warn(it2.next());
}
}
}
/**
* list all problem files
*/
private void listProblems() {
final Comparer compare = Comparer.getInstance();
final StringBuffer sb = new StringBuffer(100);
log.warn("#problems: " + compare.getProblems().size());
log.warn("problem list:");
final Iterator<FingerprintFile> it = compare.getProblems().iterator();
while (it.hasNext()) {
final FingerprintFile f = it.next();
sb.setLength(0);
sb.append(f.getPath()).append(" [").append(f.getStatus().getDescription()).append("]");
log.warn(sb);
}
}
/**
* @see java.util.Observer#update(java.util.Observable, java.lang.Object)
*/
public void update(final Observable pO, final Object pArg) {
if (pArg instanceof FingerprintFile) {
final FingerprintFile bf = (FingerprintFile)pArg;
log.warn("Found a duplicate:" + Constants.LS + bf.toString());
} else if (pArg instanceof String) {
final String str = (String)pArg;
if (pO instanceof Comparer && str.equals("stop")) {
final Comparer compare = Comparer.getInstance();
log.warn("#files: " + compare.getFiles().size());
compare.stoppedReading();
if (compare.getDuplicates().size() > 0) {
listDuplicates();
listDuplicatesSorted();
}
if (compare.getProblems().size() > 0) {
listProblems();
}
DatabaseFactory.getDatabase().close();
setRunning(false);
}
}
}
/**
* @see java.lang.Runnable#run()
*/
public void run() {
log.debug("started");
while (true) {
if (isRunning()) {
synchronized (this) {
try {
wait(100L);
} catch (final InterruptedException e) {
break;
}
}
} else {
break;
}
try {
if (System.in.available() > 0) {
final int c = System.in.read();
if (c == 'Q' || c == 'q') {
Comparer.getInstance().setRunning(false);
setRunning(false);
}
}
} catch (final IOException e) {
log.error("Error while waiting for Q key.", e);
}
}
log.debug("stopped");
}
/**
* @return boolean - Returns the running.
*/
public synchronized boolean isRunning() {
return running;
}
/**
* Sets the running to the value of pRunning.
*
* @param pRunning boolean - The new value.
*/
public synchronized void setRunning(final boolean pRunning) {
running = pRunning;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -