2015-03-19 83 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