diff --git a/dependency-check-utils/src/main/java/org/owasp/dependencycheck/utils/Checksum.java b/dependency-check-utils/src/main/java/org/owasp/dependencycheck/utils/Checksum.java index 28842818d..7d02ed90f 100644 --- a/dependency-check-utils/src/main/java/org/owasp/dependencycheck/utils/Checksum.java +++ b/dependency-check-utils/src/main/java/org/owasp/dependencycheck/utils/Checksum.java @@ -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 { /** *

- * Creates the cryptographic checksum of a given file using the specified algorithm.

+ * Creates the cryptographic checksum of a given file using the specified + * algorithm.

* * @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(); + */ } /**