2011-11-29 89 views
2

我有一个下载PDF处理程序:该进程无法访问该文件,因为它正在使用由另一个进程(iTextSharp的C#)

// Build the PDF 
    Manual.Functions.createEntireManual(ThisDownload.FileLocation); 

    // Download file 
    context.Response.Clear(); 
    context.Response.Buffer = false; 
    context.Response.ContentType = "application/pdf"; 
    context.Response.AddHeader("Content-disposition", "attachment; filename=Construct2-Manual-Full.pdf");   
    context.Response.AddHeader("Content-Length", FileSize.ToString()); 
    context.Response.TransmitFile(Settings.ManualBinLocation + ThisDownload.ID + ".pdf"); 
    context.Response.Close(); 

的创建手动功能如下:

public static void createEntireManual(string PDFPath) 
{ 
    iTextSharp.text.Document d = new iTextSharp.text.Document(); 
    d.Open(); 

    using (iTextSharp.text.pdf.PdfWriter p = iTextSharp.text.pdf.PdfWriter.GetInstance(d, new FileStream(PDFPath, FileMode.Create))) 
    { 
     d.Add(new Paragraph("Hello world!")); 
    }    
} 

这引发错误:

Exception Details: System.IO.IOException: The process cannot access the file 'C:\inetpub\wwwroot\manuals\26.pdf' because it is being used by another process. 

很好,所以我在函数中添加d.Close()

 d.Add(new Paragraph("Hello world!"));    
    }  
    d.Close();   
} 

但这抛出:

Exception Details: System.Exception: The document is not open. 

d.Close()线。我尝试添加新的Document对象作为使用语句,但它不喜欢这样,抛出无意义的错误:

Exception Details: System.Exception: The document is not open. 

关于使用右括号。

iTextSharp更有经验的人能帮我一个忙吗?

+0

我不确定这是否是答案,但您可能需要关闭您创建的'FileStream',而不是'iTextSharp.text.Document'。我不在VS面前,所以我无法测试它。 – Timiz0r

回答

0

想通了,你根本不应该使用using作为DocumentPDFWriter的对象。此代码的工作:

/// <summary> 
    /// Saves the entire manual as PDF 
    /// </summary> 
    public static void createEntireManual(string PDFPath) 
    { 
     Document d = new Document(); 
     PdfWriter.GetInstance(d, new FileStream(PDFPath, FileMode.Create)); 
     d.Open(); 
     d.SetPageSize(iTextSharp.text.PageSize.A4); 
     Image Cover = Image.GetInstance(Settings.ManualBinLocation + "cover.png"); 
     Cover.SetAbsolutePosition(0, 0); 
     d.Add(Cover); 
     d.Close();    

    } 
+0

静态方法?没有锁? asp.net?文件系统?并发灾难的配方。 – x0n

+0

@ z0n最好的办法是什么?我需要它来构建PDF,然后提供它。 –

+0

想想如果两个人在大致相同的时间请求相同但尚未创建的PDF,会发生什么情况。这里有一个很好的并发和线程教程,我总是推荐:http://www.albahari.com/threading/ – x0n

2

需要保存PDF文件系统?否则,直接使用对象的OutputStream要容易得多。这里有一个简单的例子:

<%@ WebHandler Language="C#" Class="handlerExample" %> 
using System; 
using System.Web; 
using iTextSharp.text; 
using iTextSharp.text.pdf; 

public class handlerExample : IHttpHandler { 
    public void ProcessRequest (HttpContext context) { 
    HttpResponse Response = context.Response; 
    Response.ContentType = "application/pdf"; 
    Response.AddHeader(
     "Content-disposition", 
     "attachment; filename=Construct2-Manual-Full.pdf" 
    ); 
    using (Document document = new Document()) { 
     PdfWriter.GetInstance(
     document, Response.OutputStream 
    ); 
     document.Open(); 
     document.Add(new Paragraph("Hello World!")); 
    } 
    } 
    public bool IsReusable { get { return false; } } 
} 

所以说你不应该使用using说法是不正确。上面的例子简化了,但可以很容易地扩展;从你上面命名你的方法的方式来看,也许你正在从许多不同的小PDF文档中构建PDF手册?

相关问题