这是我的两个代码片段:
public class Uploader {
private static final String SHA_256 = "SHA-256";
public String getFileSHA2Checksum(InputStream fis) throws IOException {
try {
MessageDigest md5Digest = MessageDigest.getInstance(SHA_256);
return getFileChecksum(md5Digest, fis);
} catch (NoSuchAlgorithmException e) {
return "KO";
}
}
public void transferTo(InputStream fis) throws IOException {
FileUtils.copyInputStreamToFile(fis, file2);
}
我的代码使用这个类作为:
是否可以同时
copyToFile
和calculateChecksum
杠杆InputStream
是开放的?
DigestInputStream
在从流中读取时计算哈希值。也就是说,您用 DigestInputStream
包装原始输入流并通读 DigestInputStream
.
DigestOutputStream
在写入流时计算哈希。以类似的方式,您用 DigestOutputStream
包装目标输出流并写入 DigestOutputStream
.
一个快速而肮脏的例子:
var inputFile = Path.of("D:\\Development\\data\\testdata-csv\\customers-1000.csv");
var outputFile = Files.createTempFile("testoutput", ".dat");
var md = MessageDigest.getInstance("SHA-256");
try (var in = new DigestInputStream(Files.newInputStream(inputFile), md);
var out = Files.newOutputStream(outputFile)) {
in.transferTo(out);
} finally {
Files.deleteIfExists(outputFile);
}
System.out.println(HexFormat.of().formatHex(md.digest()));
就您现有的代码而言,您可以执行以下操作:
public String transferAndHash(InputStream in) throws IOException {
try {
var md = MessageDigest.getInstance("SHA-256");
try (var digestIn = new DigestInputStream(in, md)) {
transferTo(digestIn);
}
return HexFormat.of().formatHex(md.digest());
} catch (NoSuchAlgorithmException e) {
// all recent Java versions are required to support SHA-256
throw new AssertionError("Expected SHA-256 to be supported", e);
}
}
(注意:
HexFormat
是在 Java 17 中引入的,如果您使用的是更早的版本,则需要一个替代版本。)
这里是一个使用
DigestInputStream
的例子,基于Mark Rotteveel的建议(我喜欢):
Path input = Paths.get("input_file");
Path output = Paths.get("output_file");
MessageDigest algorithm = MessageDigest.getInstance("SHA-256");
try (InputStream is = Files.newInputStream(input);
DigestInputStream hashingStream = new DigestInputStream(is, algorithm)) {
Files.copy(hashingStream, output);
}
byte[] digest = algorithm.digest();
// this line uses Apache Commons Codec to show the hex representation of the byte[]
String hash = Hex.encodeHexString(digest);
如果你想读取一次输入流,你可以手动从输入字符串中读取字节并自己写入你的文件。
private static final String SHA_256 = "SHA-256";
private static final int BUFFER = 1024;
public String writeToFile(InputStream fis, File outputFile) throws IOException {
try (var fout = new FileOutputStream(outputFile); fis) {
MessageDigest md5Digest = MessageDigest.getInstance(SHA_256);
var buffer = new byte[BUFFER];
var bytesRead = 0;
while (true) {
bytesRead = fis.read(buffer);
if (bytesRead < 0)
break;
md5Digest.update(buffer, 0, bytesRead);
fout.write(buffer, 0, bytesRead);
}
var checksume = md5Digest.digest();
return Hex.encodeHexString(checksume);
} catch (NoSuchAlgorithmException e) {
return "KO";
}
}