CSDN上传文件时,会快速判断文件是否已经存在,很好奇,于是在网上查找比较两个文件相等的方法,了解到可以采用信息摘要算法判断两个文件内容是否相等。也对上次面试题有了新的解法(上次是先比较大小再一个字节一个字节对比的)。
解法如下:
根据MD5值计算两个文件是否相等
//参数为两个文件的文件路径
public static boolean checkByMD5(String pathA, String pathB) {
FileInputStream fileA = null;
FileInputStream fileB = null;
try {
fileA = new FileInputStream(pathA);
fileB = new FileInputStream(pathB);
int lenA = fileA.available();// 文件A的大小
int lenB = fileA.available();// 文件B的大小
if (lenA != lenB) {
return false;// 大小不等直接返回
}
// 否则再判断文件内容是否相等 逐个判断
String MD5a = getFileMD5(fileA);
String MD5b = getFileMD5(fileB);
if (MD5a.equals(MD5b))
return true;
return false;
} catch (FileNotFoundException e) {
// System.out.println("文件"+pathB+"不存在");
return false;// 文件不存在 则直接返回false
} catch (Exception e) {
// TODO: handle exception
System.out.println(e.toString());
return false;
} finally {
// 关闭输入流
try {
if (fileA != null)
fileA.close();
if (fileB != null)
fileB.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static String getFileMD5(FileInputStream file) {
if (file == null)
return "";
MessageDigest digest = null;
byte buffer[] = new byte[8192];
int len;
try {
digest = MessageDigest.getInstance("MD5");
while ((len = file.read(buffer)) != -1) {
digest.update(buffer, 0, len);
}
BigInteger bigInt = new BigInteger(1, digest.digest());
return bigInt.toString(16);
} catch (Exception e) {
e.printStackTrace();
return "";
}
}
根据Sha1信息摘要算法比较像个文件是否相等。
public static boolean checkBySha1(String pathA, String pathB) {
FileInputStream fileA = null;
FileInputStream fileB = null;
try {
fileA = new FileInputStream(pathA);
fileB = new FileInputStream(pathB);
int lenA = fileA.available();// 文件A的大小
int lenB = fileA.available();// 文件B的大小
if (lenA != lenB) {
return false;// 大小不等直接返回
}
// 否则再判断文件内容是否相等 逐个判断
String MD5a = getFileSha1(fileA);
String MD5b = getFileSha1(fileB);
if (MD5a.equals(MD5b))
return true;
return false;
} catch (FileNotFoundException e) {
// System.out.println("文件"+pathB+"不存在");
return false;// 文件不存在 则直接返回false
} catch (Exception e) {
// TODO: handle exception
System.out.println(e.toString());
return false;
} finally {
// 关闭输入流
try {
if (fileA != null)
fileA.close();
if (fileB != null)
fileB.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static String getFileSha1(FileInputStream file) {
if(file==null)
return "";
MessageDigest digest = null;
byte buffer[] = new byte[8192];
int len;
try {
digest = MessageDigest.getInstance("SHA-1");
while ((len = file.read(buffer)) != -1) {
digest.update(buffer, 0, len);
}
BigInteger bigInt = new BigInteger(1, digest.digest());
return bigInt.toString(16);
} catch (Exception e) {
e.printStackTrace();
return "";
}
}
补充说明:
MessageDigest类
功能:提供信息摘要算法,如MD5、SHA-1、SHA-256
信息摘要是安全的单向散列函数,可以采用任意大小的数据并输出固定长度的散列值。
使用方法:
import java.security.MessageDigest;
import javax.xml.bind.DatatypeConverter;
public class testMD5 {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String myInfo = "今天天气真好";
MessageDigest md = null;
try {
md = MessageDigest.getInstance("MD5");
md.update(myInfo.getBytes());
byte[] res = md.digest();
//DatatypeConverter.printHexBinary(byte[] val):Converts an array of bytes into a string.
//结果为5BB7CCE17D3DD1CB71E2F3A3526990D2
System.out.println(DatatypeConverter.printHexBinary(res));
} catch (Exception e) {
// TODO: handle exception
}
}
}