C# PDF 删除 - 文件 'being used by another process'

标签 c# pdf itext ioexception delete-file

我广泛搜索了这个问题的答案。我知道为什么我会收到异常,但我终生无法在我的代码中找到它的原因。

基本上,我的代码会创建四个单独的 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]);
        }
    }
}

如有任何帮助,我们将不胜感激。当我合并文档时,我假设在循环中的某个地方,某些东西没有被关闭(读者/作者),但我尝试了很多不同的组合,但似乎没有任何效果。这真的开始让我烦恼了。

更新 谢谢大家的评论。我已将我的代码修改为:

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;
}

它可以编译,但我在运行时收到错误,指向 Using 循环的右大括号:

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

最佳答案

您没有处置任何您的资源。

PdfReaderPdfWriterFileStream 都实现了 IDisposable。这些都需要被 Disposed 或包装在 using block 中(最好是后者)。

我猜是 PdfReader 实例使这些文件保持打开状态。

附言仅在方法结束时 Close 它们是不够的,因为如果在这些调用执行之前发生任何异常,这将使它们“永久”打开(或只要进程运行)。要么将清理放在 finally block 中,要么只使用 using

关于C# PDF 删除 - 文件 'being used by another process',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15589493/

相关文章:

c# - 阅读 PDF 并找到要添加到列表中的特定列

c# - 从 XSLT 中的变量集输出回车

c# - 遍历 0's and 1' 的 int[,] 数组

c# - 是否可以在 C# 中使用 Moq 从另一个模拟返回一个模拟?

c# - 如何避免 Entity Framework 中硬编码字段名称?

java - 为什么我不能在 java ee 项目中使用 PDDOCUMENT PDFBOX ?

hadoop - 如何解析多个pdf转换成hadoop(例子)

ios - 从核心数据和 TableView Controller 创建 PDF 文档

pdf - 为什么这两个 itext 7 签名和验证文档之一对 Adob​​e DC 阅读器无效?

excel - 在 itextSharp 中使用 LocationTextExtractionStrategy 获取文本坐标