2015-03-19 76 views
1

我正在使用iTextSharp將頁碼添加到使用C#的PDF中。在運行代碼分析時,輸出的MemoryStream被懷疑會被處理多次。 See this warning generated by Visual Studio.這是一個API問題嗎? PdfStamper的第二個參數是否應該標記爲out?有沒有辦法讓我解決這個警告?是PDF處理器處理輸出流嗎? (iTextSharp)

MemoryStream mem = null; 
PdfReader reader = null; 
PdfStamper stamper = null; 
try 
{ 
    mem = new MemoryStream(); 
    reader = new PdfReader(m_pdf);     
    stamper = new PdfStamper(reader, mem); 

    // do stuff 
    stamper.Close(); 
    var result = mem.ToArray(); 
} 
finally 
{ 
    if(stamper != null) 
    { 
     stamper.Dispose(); 
    } 

    if (reader != null) 
    { 
     reader.Dispose(); 
    } 

    if (mem != null) 
    { 
     mem.Dispose(); 
    } 
} 
+1

我是iText(其他人將它移植到C#)的開發人員,並且基於我對iText的瞭解,當我看到您的代碼時,我很擔心。我不知道'PdfStamper'中的Dispose()方法,但是我知道你總是需要'stamper.Close()'。 'Close()'方法也關閉了底層的輸出流。在關閉'stamper'之前關閉輸出流*是非常錯誤的,因爲這會導致截斷(不正確)的PDF文件。 – 2015-03-19 10:16:42

+0

我在處理'stamper'之前處理'reader'的問題相同。如果'stamper'需要'reader'中的資源來完成PDF創建過程,則會拋出一個錯誤,因爲它將不再訪問關閉的'reader'。我更喜歡防禦性編程,所以我會切換這兩個,以便在處理'reader'之前處理'stamper'。 – 2015-03-19 10:20:39

+0

@BrunoLowagie你說的對,'Close()'丟失了。我編輯了代碼,特別是處理對象的順序。我想這可以防止任何可能的問題雙重處置。 – aggsol 2015-03-19 10:27:54

回答

3

這是不是一個真正的答案,但要在什麼@mkl說擴大,切換到using指令,因爲這些自動爲您執行try/finally東西。

以下是我(通常會使用iTextSharp的其他人)通常會推薦與iTextSharp交互的方式。外部using是BCL的東西,在這種情況下,MemoryStream和內部using語句是iTextSharp的東西。

//Will hold our raw PDF bytes 
Byte[] result; 

//BCL stuff first 
using (var mem = new MemoryStream()) { 

    //iText stuff in the middle 
    using (var reader = new PdfReader(m_pdf)) { 
     using (var stamper = new PdfStamper(reader, mem)) { 
      // do stuff 

     } 
    } 

    //iText is completely done and disposed of at this point 
    //so we can now grab the raw bytes that represent a PDF 
    result = mem.ToArray(); 
} 

順便說一句,不一定是OP但以防萬一別人看到這個,幾乎從來沒有(和「幾乎從來沒有」我真的是「從不」)一個很好的理由關閉底層流。您可以通過抓取原始字節並再次寫入來從流中讀取,這從來沒有道理。

+1

嗯,我不知道C#,但在Java中,可能有理由不關閉流。例如:您正在向ZipOutputStream寫入多個文件。或者您的信息流是郵件信息,您需要將PDF字節寫入該信息流以添加PDF附件。我知道更多的例子,但我忘了他們;-) – 2015-03-19 17:25:54

+1

@BrunoLowagie,我拋出了「幾乎」在那裏,因爲有一些邊緣情況,但除非有人知道這些我不會推薦他們。複雜的東西,如zip文件和電子郵件通常抽象爲具有「添加」方法的對象,這些方法可以獲取文件,字節或以前創建的流。對象內部可能有一個流,但該流很少暴露。有一些開銷,是真的,但它使調試更容易。 – 2015-03-19 20:38:33