2013-12-13 23 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