我開發一個web應用程序(使用Java EE 6 GF 3.1),允許用戶上傳PDF文件。由於這是一個封閉的小型社區,因此上傳的文件已存在於系統中的機會很多。我不能僅僅檢查名稱是否存在重複,因爲它顯然是不夠的。我正在考慮散列整個文件並將條目存儲在數據庫中。這是可行的,以及如何實現這一目標?如果不是,那麼什麼是更好的方法。如何散列文件,以確定如果我已經看到它或不
回答
考慮使用校驗和。
這是http://www.exampledepot.com/egs/java.util.zip/CalculateChecksum.html
byte[] bytes = "some data".getBytes();
// Compute Adler-32 checksum
Checksum checksumEngine = new Adler32();
checksumEngine.update(bytes, 0, bytes.length);
long checksum = checksumEngine.getValue();
// Compute CRC-32 checksum
checksumEngine = new CRC32();
checksumEngine.update(bytes, 0, bytes.length);
checksum = checksumEngine.getValue();
// The checksum engine can be reused again for a different byte array by calling reset()
checksumEngine.reset();
編輯:
注意校驗絕對不能告訴你,如果兩個文件是不同的,但是他們是非常有用的。
如果兩個文件相同,他們將具有相同的校驗和。
因此,如果校驗和不同,你知道絕對的文件不同。
但是兩個不同的文件有時也可能具有相同的校驗和。
所以使用這種方式是先計算校驗 - 如果有差別,這些文件是不同的。如果它們是相同的,則必須進行逐字節的比較。當然這比較慢,但不會經常發生。
還要注意這一切適用於哈希碼爲好。
您的解決方案非常優雅。計算文件內容的散列(MD5可能足以啓動)並將其用作數據庫中的主鍵。您可以將文件保存在數據庫中,也可以保存在外部(對此有很多爭議)。
下一次有人上載文件,計算哈希值,檢查數據庫,保存,如果不存在。
是的,這是可行的。事實上,這就是P2P程序識別文件的方法。
使用任何加密哈希算法(MD5,SHA-1等)
Java有使用MessageDigest類散列支持。
但是請注意,這樣可以避免存儲重複文件,但它不會阻止用戶上傳文件:只有在服務器端,您才能訪問文件內容並對其進行哈希處理,除非您使用具有訪問本地文件權限的applet或webstart應用程序。
當然,這是可行的,可以使用MessageDigest類來做到這一點。例如:
InputStream is = // input stream of the uploaded file
byte[] buffer = new byte[1024];
byte[] digest;
try {
MessageDigest md = MessageDigest.getInstance("MD5");
for (int count = is.read(buffer); count != -1; count = is.read(buffer)) {
md.update(buffer, 0, count);
}
digest = md.digest();
// store digest as needed, possibly Base64 encode first
}
catch (NoSuchAlgorithmException e) {
// handle
}
文件上的MD5散列是否保證唯一性 - >如果兩個散列不同,則兩個文件不同,反之亦然。如果不是這樣,那麼從Md5切換到SHA-256將有助於增加唯一性的機會? –
它沒有_guarantee_唯一性,沒有散列函數可以做到這一點,但碰撞的機率很低。 SHA的衝突機率更低,但計算SHA哈希需要的時間比計算MD5哈希需要的時間更長。話雖如此,CRC可能是一個更好的選擇,正如CPerkins所指出的那樣,因爲你不需要安全的哈希。 –
在過去,我已經使用蒂莫西·W^Macinta的(可能是這樣用戶@Tim Macinta)"Fast MD5 Implementation"。
最簡單的例子是:
// imports: java.io.File and com.twmacinta.util.MD5;
String hash = MD5.asHex(MD5.getHash(new File(filename)));
此實用程序還必須使用本機庫,以提高性能的能力。
文件上的MD5散列是否保證唯一性 - >如果兩個散列不同,則兩個文件不同,反之亦然。如果不是這樣,那麼從Md5切換到SHA-256將有助於增加唯一性的機會? –
- 1. FTP遞歸...如果我已經有文件,如何跳過它?
- 2. 如何使用TFS SDK以確定如果簽出文件已經改變
- 3. 刪除文件名,如果它已經在列表
- 4. 如何覆蓋文件,如果它已經存在?
- 5. 我如何重寫已經重寫的文件,如果找不到
- 6. 確保您不會覆蓋文件,如果它已經存在於安裝
- 7. 如何獲取對象,如果它已經在列表中?
- 8. 如果我已經連接到服務器。那麼我如何顯示異常說它已經連接
- 9. 如何知道一個承諾已經實現,所以我可以鏈接到它或使用其結果?
- 10. 我已經安裝了WxWidgets,但PgAdmin看不到它
- 11. jQuery的提交功能 - 如何不有它綁定,如果已經綁定
- 12. 如何增加文件名如果文件已經存在?
- 13. 如果文件名已經存在,如何刪除文件?
- 14. 如何遞增的文件名,如果文件已經存在
- 15. NSDictionary /散列如果內容已經改變
- 16. 如何不在sqlite中記錄,如果它已經在表
- 17. 如何解散progressdialog,如果mp3已經在android中播放
- 18. 如何確定我是否已經正確實施了d3?
- 19. 如果已經顯示鍵盤矩形,我該如何得到它?
- 20. 關閉一個Excel文件,如果發現它已經打開
- 21. 覆蓋現有的XML文件,如果它已經存在
- 22. 值複製到另一個表,如果它不已經存在
- 23. 如何訪問SqlDataSource已經選擇的數據,如果它綁定到GridView?
- 24. Nginx下載文件,如果我只允許自己看到它
- 25. PHP的重定向,如果用戶已經驗證或不
- 26. 如何記錄特定異常,如果我已經使用FullAjaxExceptionHandler
- 27. 獲取我們插入的mongodb文檔的_id,如果它不存在並更新(如果它已經存在)
- 28. 如何確認散列中的所有元素都已定義?
- 29. 如果任何人都可以看看我會喜歡它
- 30. 如何FTP我已經在TXT中列出的許多文件?
聽起來很合理。文件上傳不應該太常見,並且散列計算只能執行一次,而不是計算密集型的。 –