package jef.tools;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import jef.common.log.LogUtil;
/**
* 文件比较器,用于比较两个文件是否相同
*
* @author jiyi
* @see #LENGTH_CRC
* @see #LENGTH_ONLY
* @see #LENGTH_SKIP
*/
public abstract class FileComparator {
public abstract boolean equals(File source, File target);
protected boolean compareFullContent(File source, File target) {
try {
String a = StringUtils.getCRC(IOUtils.getInputStream(source));
String b = StringUtils.getCRC(IOUtils.getInputStream(target));
return a.equals(b);
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
protected boolean compareClips(File source, File target, long len) {
if (len < 20480) {
return compareFullContent(source, target);
}
long skipsize = (len / 10) - 1024;
byte[] buf1 = new byte[1024];
byte[] buf2 = new byte[1024];
RandomAccessFile f1 = null;
RandomAccessFile f2 = null;
try {
f1 = new RandomAccessFile(source, "r");
f2 = new RandomAccessFile(target, "r");
long seek = 0;
while (seek < len) {
f1.seek(seek);
int l1 = f1.read(buf1);
f2.seek(seek);
int l2 = f2.read(buf2);
seek += skipsize;
if (!compareBuffer(buf1, l1, buf2, l2)) {
return false;
}
}
return true;
} catch (IOException e) {
LogUtil.error("CompareFileError:", e);
return false;
} finally {
IOUtils.closeQuietly(f1);
IOUtils.closeQuietly(f2);
}
}
private boolean compareBuffer(byte[] buf1, int l1, byte[] buf2, int l2) {
if (l1 != l2)
return false;
for (int i = 0; i < l1; i++) {
if (buf1[i] != buf2[i])
return false;
}
return true;
}
/**
* 比较器:比较两个文件长度,长度相同就认为相同
*/
public static FileComparator LENGTH_ONLY = new FileComparator() {
public boolean equals(File source, File target) {
if (source.isFile() && target.isFile()) {
return source.length() == target.length();
}
return false;
}
};
/**
* 比较器:将两个文件取CRC后进行比较,能够比较出全部内容上的差异
*/
public static FileComparator LENGTH_CRC = new FileComparator() {
public boolean equals(File source, File target) {
if (source.isFile() && target.isFile()) {
if (source.length() == target.length()) {
return compareFullContent(source, target);
}
}
return false;
}
};
/**
* 比较器:在文件大小相同的前提下 将文件分为10个小段,每个小段比较1024字节(抽样比较文件) 适用于大文件的快速比较
*/
public static FileComparator LENGTH_SKIP = new FileComparator() {
public boolean equals(File source, File target) {
if (source.isFile() && target.isFile()) {
long len = source.length();
if (len == target.length()) {
return compareClips(source, target, len);
}
}
return false;
}
};
/**
* 比较器,根据文件大小来选择使用哪种比较方式
*
* @author Administrator
*
*/
public static class Smart extends FileComparator {
private long length;
public Smart() {
length = 1024 * 1024 * 10;
}
public Smart(long exceed) {
this.length = exceed;
}
public boolean equals(File source, File target) {
if (source.isFile() && target.isFile()) {
long len = source.length();
if (len == target.length()) {
if (len > length) {
return compareFullContent(source, target);
} else {
return compareClips(source, target, len);
}
}
}
return false;
}
};
}