corrected checksum calculation so that files can be deleted shortly after the calculation is completed.

This commit is contained in:
Jeremy Long
2016-10-08 18:05:55 -04:00
parent 110c97bc15
commit 7fc2be6a0a

View File

@@ -23,6 +23,7 @@ import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.security.MessageDigest;
@@ -49,20 +50,61 @@ public final class Checksum {
/**
* <p>
* Creates the cryptographic checksum of a given file using the specified algorithm.</p>
* Creates the cryptographic checksum of a given file using the specified
* algorithm.</p>
*
* @param algorithm the algorithm to use to calculate the checksum
* @param file the file to calculate the checksum for
* @return the checksum
* @throws IOException when the file does not exist
* @throws NoSuchAlgorithmException when an algorithm is specified that does not exist
* @throws NoSuchAlgorithmException when an algorithm is specified that does
* not exist
*/
public static byte[] getChecksum(String algorithm, File file) throws NoSuchAlgorithmException, IOException {
final MessageDigest digest = MessageDigest.getInstance(algorithm);
MessageDigest md = MessageDigest.getInstance(algorithm);
FileInputStream fis = null;
FileChannel ch = null;
try {
fis = new FileInputStream(file);
final FileChannel ch = fis.getChannel();
ch = fis.getChannel();
ByteBuffer buf = ByteBuffer.allocateDirect(8192);
int b = ch.read(buf);
while ((b != -1) && (b != 0)) {
buf.flip();
byte[] bytes = new byte[b];
buf.get(bytes);
md.update(bytes, 0, b);
buf.clear();
b = ch.read(buf);
}
return md.digest();
} finally {
if (ch != null) {
try {
ch.close();
} catch (IOException ex) {
LOGGER.trace("Error closing channel '{}'.", file.getName(), ex);
}
}
if (fis != null) {
try {
fis.close();
} catch (IOException ex) {
LOGGER.trace("Error closing file '{}'.", file.getName(), ex);
}
}
}
/*
// while the following is likely faster, it does not work as we need to
// be able to delete the file, see
// http://stackoverflow.com/questions/24589488/why-does-this-utility-method-leaves-files-locked
//
final MessageDigest digest = MessageDigest.getInstance(algorithm);
FileInputStream fis = null;
FileChannel ch = null;
try {
fis = new FileInputStream(file);
ch = fis.getChannel();
long remainingToRead = file.length();
long start = 0;
while (remainingToRead > 0) {
@@ -79,6 +121,13 @@ public final class Checksum {
start += amountToRead;
}
} finally {
if (ch != null) {
try {
ch.close();
} catch (IOException ex) {
LOGGER.trace("Error closing channel '{}'.", file.getName(), ex);
}
}
if (fis != null) {
try {
fis.close();
@@ -88,6 +137,7 @@ public final class Checksum {
}
}
return digest.digest();
*/
}
/**