2013-03-23 362 views
1

我已經搜索了這個問題的答案。我知道爲什麼我收到異常,但我不能在我的代碼中找到它的原因。C#PDF刪除 - 正在被另一個進程使用的文件'

基本上,我的代碼創建四個獨立的PDF文件,將它們加入到大PDF文件中,然後刪除原來的四個文件。一切都很好,除非我在嘗試刪除文件時收到IOException,因爲它們正在被另一個進程使用。

下面是我用合併文件的代碼:

private static Document MergeFiles(string[] fileNames, string finalFileName) 
{ 
    Document doc = new Document(PageSize.A4, 20, 20, 25, 25); 
    if (fileNames.Length > 0) 
    { 
     int a = 0; 
     PdfReader reader = new PdfReader(fileNames[a]); 
     int n = reader.NumberOfPages; 
     FileStream output = new FileStream("C:\\temp\\" + finalFileName, FileMode.Create); 
     PdfWriter writer = PdfWriter.GetInstance(doc, output); 
     doc.Open(); 
     PdfContentByte cb = writer.DirectContent; 
     PdfImportedPage page; 
     int rotation; 

     while (a < fileNames.Length) 
     { 
      int i = 0; 
      while (i < n) 
      { 
       i++; 
       doc.SetPageSize(reader.GetPageSizeWithRotation(i)); 
       doc.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); 
      } 
      a++; 
      if (a < fileNames.Length) 
      { 
       reader = new PdfReader(fileNames[a]); 
       n = reader.NumberOfPages; 
      } 
     } 
    } 
    doc.Close(); 
    return doc; 
} 

這裏是代碼刪除文件:

private static void DeleteFile(string[] fileNames) 
{ 
    if (fileNames != null) 
    { 
     for (int x = 0; x < fileNames.Length; x++) 
     { 
      if(!fileNames[x].Equals("")) 
       System.IO.File.Delete(fileNames[x]); 
     } 
    } 
} 

任何援助將不勝感激。當我合併文檔時,我假定在某個循環的某個地方,某些東西沒有被關閉(讀寫器),但我嘗試了很多不同的組合,沒有任何東西可以工作。這真的開始讓我煩惱。

UPDATE 感謝您的意見,每個人。我已經修改了我的代碼如下:

private static Document MergeFiles(string[] fileNames, string finalFileName) 
{ 
    Document doc = new Document(PageSize.A4, 20, 20, 25, 25); 
    if (fileNames.Length > 0) 
    { 
     while (a < fileNames.Length) 
     { 
      using (PdfReader reader = new PdfReader(fileNames[a])) 
      using (FileStream output = new FileStream("C:\\temp\\" + finalFileName, FileMode.Create)) 
      using (PdfWriter writer = PdfWriter.GetInstance(doc, output)) 
      { 
       int n = reader.NumberOfPages; 
       doc.Open(); 
       PdfContentByte cb = writer.DirectContent; 
       PdfImportedPage page; 
       int rotation; 

       int i = 0; 
       while (i < n) 
       { 
        i++; 
        doc.SetPageSize(reader.GetPageSizeWithRotation(i)); 
        doc.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); 
       } 
       a++; 
       if (a < fileNames.Length) 
       { 
        n = reader.NumberOfPages; 
       } 
      } 
     } 
    } 
    doc.Close(); 
    return doc; 
} 

它編譯,但我會在運行時錯誤指向到使用循環的結束括號:雖然您要關閉

System.ObjectDisposedException was unhandled 
    Message=Cannot access a closed file. 
+0

也許在using語句中實例化PdfReader(fileName [a])? – 2013-03-23 17:08:30

+0

有幾點建議:不要返回一個'Document'對象,一旦關閉它就沒有意義了。或者返回一個成功的布爾值,文件名(可能不是因爲你將它傳入)或者可能切換到一個'MemoryStream'並返回字節數組。如果你原來的四個文檔足夠小,我也可以創建一個'MemoryStream',然後從字節數組中取出。這樣你就不必擔心有時會碰到磁盤。 – 2013-03-24 15:23:41

+0

Chris,我結束了你的解決方案,並使用MemorySteam和字節數組。它最終變得更快更容易,沒有任何與PdfReaders等相關的問題。 感謝您的建議! – 2013-03-25 06:22:46

回答

0

文件(doc.Close();),你沒有關閉文件流,作家和讀者。

doc.Close();後補充一點:

writer.Close(); 
output.Close(); 
reader.Close(); 
4

你沒有配置您的任何資源

PdfReader,PdfWriterFileStream全部實施IDisposable。這些都需要Disposed或包裹在using塊(最好是後者)。

我的猜測是PdfReader正在保存這些文件的實例。

P.S.僅僅在方法結尾處僅有Close是不夠的,因爲如果在這些調用執行之前發生任何異常,這將使它們「永久」(或只要進程運行)打開。請將您的清理放在finally區塊中,或者僅使用using

+0

非常感謝,亞倫。你能提供一個我如何在這個實例中實例化using語句的快速例子嗎?我是新的(截至昨天!)使用語句:) – 2013-03-24 00:30:49

+0

@ BennyO'Neill http://msdn.microsoft.com/en-ca/library/yh598w02.aspx – Aaronaught 2013-03-24 00:45:35

+0

對不起,我應該澄清。我知道使用這個語句的一般方法,但我並不完全知道如何在這個例子中使用它。 例如我已經做 「使用(PDFReader讀者=新PDFReader(文件名[0])) { //代碼 }」 除I「,因爲它是一個無法分配給讀者使用可變收到一個編譯錯誤「在使用塊內部的這條線上: 'reader = new PdfReader(fileNames [a]);' – 2013-03-24 01:01:49

相關問題