Using Java 1.8, I created a class which obtains a zip file from an external HTTP URL:
e.g.
https://raw.githubusercontent.com/mlampros/DataSets/master/fastText_data.zip
and converts it into a String based MD5 hash:
6aa2fe666f83953a089a2caa8b13b80e
My utility class:
public class HashUtils {
public static String makeHashFromUrl(String fileUrl) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
InputStream is = new URL(fileUrl).openStream();
try {
is = new DigestInputStream(is, md);
// Up to 8K per read
byte[] ignoredBuffer = new byte[8 * 1024];
while (is.read(ignoredBuffer) > 0) { }
} finally {
is.close();
}
byte[] digest = md.digest();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < digest.length; i++) {
sb.append(Integer.toString((digest[i] & 0xff) + 0x100, 16).substring(1));
}
return sb.toString();
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
}
Whereas this is fine for an external URL containing zip file (or any file with any type of file extension), I need to be be able to use the same code (algorithm) for files that reside on a local filesystem.
e.g.
Inside $CATALINA_HOME/temp/fastText_data.zip
Would need to use this instead:
InputStream fis = new FileInputStream(filename);
How could I do this using the same method (don't want to violate DRY - Don't Repeat Yourself)?
Of course, creating a brand new method containing the same code but using the InputStream fis = new FileInputStream(filename);
instead of InputStream is = new URL(fileUrl).openStream();
would be violating the DRY principle?
What would be a good way to refactor this out? Two public methods with a refactored private method containing the same lines of code?