2013-12-13 25 views
1

我已经得到了一些代码为itextsharp合并2个pdf文件。在某处找到它。合并工作正常,但似乎源文件完成后仍在使用。我想要做的是删除我已经合并的第一个文件,它通过fileupload上传,并且只保留合并的文件。这绝对是执行合并的代码,导致文件保持打开状态。我试图删除服务器上的文件,它告诉我有一些像IIShelper打开的文件。通过几小时的工作,我缩小到了这个东西。为什么它保持文件在使用中?itextsharp不关闭文件

public static void MergeFiles(string destinationFile, string[] sourceFiles) 
    { 

     int f = 0; 
     // we create a reader for a certain document 
     PdfReader reader = new PdfReader(sourceFiles[f]); 
     // we retrieve the total number of pages 
     int n = reader.NumberOfPages; 
     // step 1: creation of a document-object 
     Document document = new Document(reader.GetPageSizeWithRotation(1)); 
     // step 2: we create a writer that listens to the document 
     PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(destinationFile, FileMode.Create)); 
     // step 3: we open the document 
     document.Open(); 
     PdfContentByte cb = writer.DirectContent; 
     PdfImportedPage page; 
     int rotation; 
     if(reader.IsEncrypted() == false) 
     { 
      // step 4: we add content 
      while (f < sourceFiles.Length) 
      { 
       int i = 0; 
       while (i < n) 
       { 
        i++; 
        document.SetPageSize(reader.GetPageSizeWithRotation(i)); 
        document.NewPage(); 
        page = writer.GetImportedPage(reader, i); 
        rotation = reader.GetPageRotation(i); 
        if (rotation == 90 || rotation == 270) 
        { 
         cb.AddTemplate(page, 0, -1f, 1f, 0, 0, reader.GetPageSizeWithRotation(i).Height); 
        } 
        else 
        { 
         cb.AddTemplate(page, 1f, 0, 0, 1f, 0, 0); 
        } 
       } 
       f++; 
       if (f < sourceFiles.Length) 
       { 
        reader = new PdfReader(sourceFiles[f]); 
        // we retrieve the total number of pages 
        n = reader.NumberOfPages; 
       } 

      } 
     } 
     else 
     { 
      //is encrypted 
     } 
     // step 5: we close the document 
     document.Close(); 
     reader.Close(); 
     reader.Dispose(); 


    } 

在此先感谢

回答

3

你只在最后关闭一个reader,但每个文件打开一个阅读器。因此,只有最后的reader将被关闭。

您需要关闭旧的读者在此之前

reader = new PdfReader(sourceFiles[f]); 
+0

我看到了逻辑,但我似乎无法弄清楚如何去做。我已经试过在所有地方添加reader.close语句无济于事。有时也会引发其他问题。你能否让我知道如何恰当地关闭读者? – user3100712

0

有一两件事我注意到的是,你是不是收出你正在构建FileStream对象。由于FileStream类实现了IDisposable,因此我强烈建议您将代码封装在一个使用块中,以便适当地清理资源。

using(var destinationFileStream = new FileStream(destinationFile, FileMode.Create)) 
    { 
     PdfWriter writer = PdfWriter.GetInstance(document, destinationFileStream)); 
     // step 3: we open the document 
     document.Open(); 
     PdfContentByte cb = writer.DirectContent; 
     PdfImportedPage page; 
     int rotation; 
     if(reader.IsEncrypted() == false) 
     { 
      // step 4: we add content 
      while (f < sourceFiles.Length) 
      { 
       int i = 0; 
       while (i < n) 
       { 
        i++; 
        document.SetPageSize(reader.GetPageSizeWithRotation(i)); 
       document.NewPage(); 
       page = writer.GetImportedPage(reader, i); 
       rotation = reader.GetPageRotation(i); 
       if (rotation == 90 || rotation == 270) 
       { 
        cb.AddTemplate(page, 0, -1f, 1f, 0, 0, reader.GetPageSizeWithRotation(i).Height); 
       } 
       else 
       { 
        cb.AddTemplate(page, 1f, 0, 0, 1f, 0, 0); 
       } 
      } 
      f++; 
      if (f < sourceFiles.Length) 
      { 
       reader = new PdfReader(sourceFiles[f]); 
       // we retrieve the total number of pages 
       n = reader.NumberOfPages; 
      } 

     } 
    } 
    else 
    { 
     //is encrypted 
    } 
} 
+0

谢谢。我已经尝试过修改。出于某种原因使用此修订版使得生成的合并文件无效,也据我所知,它并未解决释放源文件的原始问题。有什么想法吗? – user3100712

+0

您可能想尝试在使用语句中包装阅读器和文档。由于您在阅读器上调用Dispose(),这意味着它可能正在实现IDisposable。您可能还想看看您构建的Writer是否正在实现IDisposable(尝试将其封装在使用语句中)。如果不是,请查看您是否可以调用Close()。我希望这有帮助 – MDiesel

0

好吧,这就是我最后的结果。

public static void MergeFiles(string destinationFile, string[] sourceFiles) 
    { 

     int f = 0; 
     // we create a reader for a certain document 
     //PdfReader reader = new PdfReader(sourceFiles[f]); 
     PdfReader reader = new PdfReader(new RandomAccessFileOrArray(sourceFiles[f], true), null); 
     if (reader.IsEncrypted() == false) 
     { 
      // we retrieve the total number of pages 
      int n = reader.NumberOfPages; 
      // step 1: creation of a document-object 
      Document document = new Document(reader.GetPageSizeWithRotation(1)); 
      // step 2: we create a writer that listens to the document 
      using(var destinationFileStream = new FileStream(destinationFile, FileMode.Create)) 
      { 
       PdfWriter writer = PdfWriter.GetInstance(document, destinationFileStream); 
       // step 3: we open the document 
       document.Open(); 
       PdfContentByte cb = writer.DirectContent; 
       PdfImportedPage page; 
       int rotation; 

        // step 4: we add content 
        while (f < sourceFiles.Length) 
        { 
         int i = 0; 
         while (i < n) 
         { 
          i++; 
          document.SetPageSize(reader.GetPageSizeWithRotation(i)); 
          document.NewPage(); 
          page = writer.GetImportedPage(reader, i); 
          rotation = reader.GetPageRotation(i); 
          if (rotation == 90 || rotation == 270) 
          { 
           cb.AddTemplate(page, 0, -1f, 1f, 0, 0, reader.GetPageSizeWithRotation(i).Height); 
          } 
          else 
          { 
           cb.AddTemplate(page, 1f, 0, 0, 1f, 0, 0); 
          } 
         } 
         f++; 
         if (f < sourceFiles.Length) 
         { 

          reader = new PdfReader(sourceFiles[f]); 
          // we retrieve the total number of pages 
          n = reader.NumberOfPages; 
         } 

        } 
        //close everything 
        document.Close(); 
        reader.Close(); 
        destinationFileStream.Close(); 
      } 

     } 
     else 
     { 
      //is encrypted 
      reader.Close(); 
     } 

    } 

我尝试了关闭阅读器等的每种可能的组合,但似乎无论什么itext保持源文件打开。

将PdfReader reader = new PdfReader(sourceFiles [f])更改为PdfReader reader = new PdfReader(new RandomAccessFileOrArray(sourceFiles [f],true),null)会产生什么效果。

RandomAccessFileOrArray取得了不同。

我不是一个itextsharp专家。有人可以向我解释为什么在这种情况下,这对迭代释放文件有如此大的影响?

1

下面是我所做的:我创建了一个我合并的文件的所有读者列表,以便跟踪它们,然后我最终关闭它们。

List<PdfReader> readers = new List<PdfReader>(); 
     try 
     { 
      int f = 0; 

      //PdfReader reader = new PdfReader(sSrcFile[f]); 

      readers.Add(new PdfReader(sSrcFile[f])); 

      int n = readers[f].NumberOfPages; 
      //Response.Write("There are " + n + " pages in the original file.\n"); 
      Document document = new Document(PageSize.A4); 

      PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(destinationFile, FileMode.Create)); 

      document.Open(); 
      PdfContentByte cb = writer.DirectContent; 
      PdfImportedPage page; 

      int rotation; 
      while (f < sSrcFile.Length) 
      { 
       int i = 0; 
       while (i < n) 
       { 
        i++; 

        document.SetPageSize(PageSize.A4); 
        document.NewPage(); 
        page = writer.GetImportedPage(readers[f], i); 

        rotation = readers[f].GetPageRotation(i); 
        if (rotation == 90 || rotation == 270) 
        { 
         cb.AddTemplate(page, 0, -1f, 1f, 0, 0, readers[f].GetPageSizeWithRotation(i).Height); 
        } 
        else 
        { 
         cb.AddTemplate(page, 1f, 0, 0, 1f, 0, 0); 
        } 
        //Response.Write("\n Processed page " + i + "\n"); 
       } 

       f++; 
       if (f < sSrcFile.Length) 
       { 
        readers.Add(new PdfReader(sSrcFile[f])); 
        n = readers[f].NumberOfPages; 
        //Response.Write("ff : There are " + n + " pages in the original file.\n"); 
       } 
      } 

      //Response.Write(returnLocation); 
      document.Close(); 

      for (var i = 0; i < readers.Count; i++) 
      { 
       readers[i].Close(); 
      } 

      return returnLocation; 
     } 
     catch (Exception e) 
     { 
      Response.Write("The error message is: " + e.Message); 
      return e.Message; 
     } 
1

我在VB.net有同样的问题。您需要关闭每个阅读器,pdfDoc和作家。

Imports iTextSharp.text.pdf 
Imports iTextSharp.text 

Public Sub MergePDF_File(ByVal fileArray As String(), ByVal outPutPDF As String) 

    If fileArray Is Nothing OrElse fileArray.Length = 0 Then 
     Throw New ApplicationException("No file list") 
    End If 
    If String.IsNullOrEmpty(outPutPDF) Then 
     Throw New ApplicationException("Must specify output file") 
    End If 

    Dim pdfDoc As iTextSharp.text.Document = Nothing 
    Dim writer As iTextSharp.text.pdf.PdfCopy = Nothing 

    For i = 0 To fileArray.Length - 1 
     Using reader As New iTextSharp.text.pdf.PdfReader(fileArray(i)) 

      If i = 0 Then 
       pdfDoc = New iTextSharp.text.Document(reader.GetPageSizeWithRotation(1)) 
       writer = New iTextSharp.text.pdf.PdfCopy(pdfDoc, _ 
             New FileStream(outPutPDF, _ 
             FileMode.OpenOrCreate, _ 
             FileAccess.Write)) 
       pdfDoc.Open() 
      End If 

      Dim pageCount As Integer = reader.NumberOfPages 
      For pg = 1 To pageCount 
       pdfDoc.SetPageSize(reader.GetPageSizeWithRotation(pg)) 
       pdfDoc.NewPage() 
       Dim page As iTextSharp.text.pdf.PdfImportedPage = Nothing 
       page = writer.GetImportedPage(reader, pg) 
       writer.AddPage(page) 
      Next 

      reader.Close() 
     End Using 
    Next 

    pdfDoc.Close() 
    writer.Close() 

End Sub