Wie immer ist es ein Nachdruck aus dem Blog. https://munchkins-diary.hatenablog.com/entry/2019/10/28/230924 Ich habe in letzter Zeit nicht viel geschrieben, aber ich möchte es bald wieder aufnehmen.
Ich schrieb, dass es leicht ist, süchtig nach der Methode zu werden, die Prüfsumme der Datei in S3 abzurufen, und wie man die Prüfsumme der Datei mit Java als Bonus unten berechnet.
Ich hoffe es hilft jemandem. (Nicht zu viel)
Ich habe einen Prozess geschrieben, in dem eine Datei mit mehreren GB in S3 aufgelistet ist, und wollte es aufgrund eines Fehlers bei der nachfolgenden Verarbeitung erneut versuchen.
In diesem Fall ist es erneut verschwenderisch, die Datei erneut hochzuladen. Es besteht jedoch die Möglichkeit, dass die Zieldatei im Migrationsquellenspeicher geändert wurde. Daher möchte ich den Upload nur wiederholen, wenn ich bereits die "genau gleiche" Datei in S3 habe.
In diesem Fall ist es einfach, Prüfsummen zu vergleichen, daher habe ich den folgenden Code mit der getObjectMetaData-API von S3 geschrieben.
private boolean shouldSkip(String bucketName, String key, String md5CheckSum) {
try {
ObjectMetadata meta = s3Client.getObjectMetadata(bucketName, key);
if (meta == null || meta.getContentMD5() == null) {
log.info("meta data not exist for the file {} in bucket {}", key, bucketName);
return false;
}
log.info(
"Checksum of existing file is {} and present file checksum is {}",
meta.getContentMD5(),
md5CheckSum);
return meta.getContentMD5().equals(md5CheckSum);
} catch (SdkClientException e) {
log.error("Exception thrown while validating the checksum of the file {}", key, e);
return false;
}
}
Aber es funktioniert nicht.
ObjectMetaData # contentMD5
ist unweigerlich null.
Nach der Überprüfung scheint die Prüfsumme des vorhandenen Objekts in S3 an "Etag" anstatt an contentMD5 übergeben zu werden.
Wofür wird contentMD5 dann verwendet? Es wird zum Zeitpunkt der Aktualisierung zum HTTP-Header hinzugefügt und zur Manipulationsbestätigung (korrekte Verwendung) in S3 verwendet, sodass es nicht zurückgegeben wird, wenn ein Objekt mit get abgerufen wird.
Wenn Sie also die Prüfsumme der aus S3 abgelegten Datei wissen möchten, müssen Sie sie mit Etag vergleichen.
So was.
private boolean shouldSkip(String bucketName, String key, String md5CheckSum) {
try {
ObjectMetadata meta = this.s3Client.getObjectMetadata(bucketName, key);
if (meta == null || meta.getETag() == null) {
log.info("meta data not exist for the file {} in bucket {}", key, bucketName);
return false;
}
log.info(
"Checksum of existing file is {} and present file checksum is {}",
meta.getETag(),
md5CheckSum);
return meta.getETag().equals(md5CheckSum);
} catch (SdkClientException e) {
log.error("Exception thrown while validating the checksum of the file {}", key, e);
return false;
}
}
Das funktioniert gut. Ich hoffe es hilft jemandem.
Für diejenigen, die mit Prüfsumme gegoogelt haben und eingeflogen sind, erfahren Sie hier, wie Sie die Prüfsumme in Java berechnen.
public static String checkMd5Checksum(File file) {
try (BufferedInputStream is = new BufferedInputStream(new FileInputStream(file))) {
return DigestUtils.md5Hex(is);
} catch (Exception e) {
// Not likely to occur.
log.error(
"ERROR Happened while calculating the check sum for file {}", file.getAbsolutePath(), e);
return "NOT FOUND";
}
}
Ändern Sie für sha256 einfach DigestUtils # md5Hex
in DigestUtils # sha256Hex
.
Das war ein Memo.
Recommended Posts