【问题标题】:The process cannot access the file because it is being used by another process (iTextSharp c#)该进程无法访问该文件,因为它正在被另一个进程使用(iTextSharp c#)
【发布时间】:2011-11-29 19:47:41
【问题描述】:

我有一个下载 PDF 处理程序:

    // 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 对象添加为 using 语句,但它不喜欢这样,抛出无意义的错误:

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

关于使用右括号。

有谁对 iTextSharp 更有经验吗?

【问题讨论】:

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

标签: c# asp.net itextsharp


【解决方案1】:

需要将 PDF 保存到文件系统吗?否则,直接使用HttpResponse 对象的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 手册?

【讨论】:

    【解决方案2】:

    想通了,您根本不应该将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();              
    
        }
    

    【讨论】:

    • 静态方法?没有锁? ASP.NET?文件系统?并发灾难的秘诀。
    • @z0n 最好的方法是什么?我需要它来构建 PDF,然后提供它。
    • 想想如果两个人几乎同时请求相同但尚未创建的 PDF 会发生什么。这是我一直推荐的一个很棒的并发和线程教程:albahari.com/threading
    • @x0n 按照设计,两个人不会下载相同的手册。但它并没有反映在代码中。
    • 光说是不够的 - 如果两个人同时下载不同的手册点击你的代码会发生什么?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-17
    • 1970-01-01
    • 2010-12-10
    相关资源
    最近更新 更多