2014-11-06 21 views
0

如果我使用代碼 訪問PDF以在定製屬性中添加某些內容,請參閱File src_2 = new File(embed_source); 文件dest_2 =新文件(embed_destination_2);當更改PDF然後刪除更改時,恢復的文件的散列和原始文件是不同的

    try { 
         FileUtils.copyFile(src_2, dest_2); 
        } catch (IOException e) { 
         e.printStackTrace(); 
        }   
public void manipulatePdf(String src, String dest) throws IOException, DocumentException { 
      PdfReader reader = new PdfReader(src); 
      PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest)); 
      Map<String, String> info = reader.getInfo(); 
      System.out.println(info.get("Lala")); 

      stamper.setMoreInfo((HashMap<String, String>) info); 
      stamper.close(); 
      reader.close(); 
     } 

我沒有改變任何有關src文件,我所做的只是獲取有關src文件的一些信息。但是,在運行該程序之前和之後,我從src文件中得到了2個不同的哈希結果。我可以知道爲什麼嗎?

回答

1

如果您閱讀ISO-32000-1,您應該知道沒有兩個PDF等於設計。一兩個PDF文件之間的最典型的差異是ID:

從ISO-32000-1:

ID:構成文件的標識符的兩個字節的字符串數組。

從第14.4節,題爲「文件標識符」:

該項的值應是兩個字節的字符串數組。第一個字節字符串應該是基於文件最初創建時的內容的永久標識符,並且在文件增量更新時不會更改。 第二個字節字符串應該是基於上次更新時文件內容的變化標識符。當第一次寫入文件時,兩個標識符應設置爲相同的值。如果在解析文件引用時兩個標識符都匹配,則很可能找到了正確且未更改的文件。如果只有第一個標識符匹配,則找到不同版本的正確文件。

如果從頭開始創建PDF,則ID由兩個相同的標識符組成。 當您更新PDF以添加內容時,將保留第一個ID,更改第二個ID。如果您更新PDF以刪除某些內容,則第二個ID會再次發生更改,但根據定義,它不應該與第一個ID相同,因爲您處於工作流程的不同部分。

注意:沒有那麼多工具可以創建標識符相同的PDF文件。這是因爲從頭開始創建的PDF通常在最終版本保存到磁盤之前進行處理。只需使用Adobe Acrobat創建一個PDF來重現這一點:您會注意到標識符對由兩個不同的值組成。這使得詢問:是否可以創建一個我們使第二個標識符與第一個標識符相同的情況是沒有用的?

此外:PDF固有的對象組織方式是隨機的。您使用散列的使用情況違背了PDF標準。

如何解決這個問題?

你是誰問的問題是同一人[如何] Add/delete/retrieve information from a PDF using a custom property

在我回答這個問題,我將解釋如何將元數據添加到現有的PDF:

PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest)); 

這將創建一個新的PDF文件,其中對象正在重新排序。

但是,你可以改變這一行到:

PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest), '\0', true); 

現在你創建PDF文件的增量更新

什麼是增量更新?

假設您原始PDF文件看起來是這樣的:

%PDF-1.4 
% plenty of PDF objects and PDF syntax 
%%EOF 

當您使用iText的操縱這樣一個文件,你會得到一個改變PDF文件

%PDF-1.4 
% plenty of altered PDF objects and altered PDF syntax 
%%EOF 

在這個過程中,對象可以被重新編號,重新組織等等。如果你在第一步中添加一些東西,並在第二步中刪除某些東西,你可以期望PDF當在PDF閱讀器中打開文檔時,它與人眼相同,但您不應該期望PDF語法是相同的。這種假設會揭示PDF格式的缺乏洞察力。

但是,當您使用PdfStamper附加模式執行增量更新,你會得到一個增量更新PDF

%PDF-1.4 
% plenty of PDF objects and PDF syntax 
%%EOF 
% updates for PDF objects and PDF syntax 
%%EOF 

在這種情況下,原始PDF的原始字節AREN」沒有改變。文件的大小會變得更大,因爲你現在會有一些冗餘信息(一些對象將不再被使用,一些對象會有一箇舊版本以及一個新版本),但是使用增量更新的優點是你總是可以回到原始文件。

這足以搜索的%%EOF倒數第二個亮相,並刪除所有後面的字節,你會得到一個截斷PDF文件

%PDF-1.4 
% plenty of PDF objects and PDF syntax 
%%EOF 

您現在可以利用這個哈希截取的PDF文件並將其與原始PDF文件的散列進行比較。這些哈希將是相同的。

警告:謹防遵循%%EOF的空白字符。它們可以在字節級引起最小的差異,導致哈希值不同。

+0

非常感謝!這真的有幫助 – brian 2014-11-06 09:03:46

+0

是的,當我回答評論時,我沒有想過增量更新。通常,當我寫出真實的答案時,這些想法就會開始出現。這就是爲什麼在StackOverflow上提出問題的開發人員應該創建新問題,而不是使用註釋部分。我一般這樣說:我不是要批評特定的人;-) – 2014-11-06 09:30:16

+0

明白了!再次感謝 – brian 2014-11-07 02:08:28

相關問題