我正在创建一个程序,通过将文件的 MD5 与已检查的 MD5 的数据库进行比较来检查文件。
它遍历数千个文件,我看到它使用了大量内存。
如何使我的代码尽可能高效?
for (File f : directory.listFiles()) {
String MD5;
//Check if the Imagefile instance is an image. If so, check if it's already in the pMap.
if (Utils.isImage(f)) {
MD5 = Utils.toMD5(f);
if (!SyncFolderMapImpl.MD5Map.containsKey(MD5)) {
System.out.println("Adding " + f.getName() + " to DB");
add(new PhotoDTO(f.getPath(), MD5, albumName));
}
}
这是 toMD5:
public static String toMD5(File file) throws IOException, NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance("MD5");
FileInputStream fis = new FileInputStream(file.getPath());
byte[] dataBytes = new byte[8192];
int nread = 0;
while ((nread = fis.read(dataBytes)) != -1) {
md.update(dataBytes, 0, nread);
}
byte[] mdbytes = md.digest();
//convert the byte to hex format method 2
StringBuffer hexString = new StringBuffer();
for (int i = 0; i < mdbytes.length; i++) {
String hex = Integer.toHexString(0xff & mdbytes[i]);
if (hex.length() == 1) hexString.append('0');
hexString.append(hex);
}
return hexString.toString();
}
编辑:尝试使用 FastMD5。结果相同。
public static String toMD5(File file) throws IOException, NoSuchAlgorithmException {
return MD5.asHex(MD5.getHash(file));
}
编辑 2尝试使用 ThreadLocal 和 BufferedInputStream。我仍然有很多内存使用量。
private static ThreadLocal<MessageDigest> md = new ThreadLocal<MessageDigest>(){
protected MessageDigest initialValue() {
try {
return MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
System.out.println("Fail");
return null;
}
};
private static ThreadLocal<byte[]> dataBytes = new ThreadLocal<byte[]>(){
protected byte[] initialValue(){
return new byte[1024];
}
};
public static String toMD5(File file) throws IOException, NoSuchAlgorithmException {
// MessageDigest mds = md.get();
BufferedInputStream fis = new BufferedInputStream(new FileInputStream(file));
// byte[] dataBytes = new byte[1024];
int nread = 0;
while ((nread = fis.read(dataBytes.get())) != -1) {
md.get().update(dataBytes.get(), 0, nread);
}
byte[] mdbytes = md.get().digest();
//convert the byte to hex format method 2
StringBuffer hexString = new StringBuffer();
fis.close();
System.gc();
return javax.xml.bind.DatatypeConverter.printHexBinary(mdbytes).toLowerCase();
// return MD5.asHex(MD5.getHash(file));
}