简体   繁体   English

C#PDF删除 - 文件'被另一个进程使用'

[英]C# PDF Delete - File 'being used by another process'

I've searched far and wide for an answer to this question. 我已经广泛搜索了这个问题的答案。 I know WHY I'm received the exception, but I can't for the life of find the cause of it in my code. 我知道为什么我收到了异常,但我不能在我的代码中找到它的原因。

Basically, my code creates four separate PDF files, joins them into on big PDF file and then deletes the original four files. 基本上,我的代码创建了四个单独的PDF文件,将它们连接到大PDF文件上,然后删除原始的四个文件。 Everything words fine, except I receive an IOException when trying to delete the files because they are 'being used by another process.' 一切都很好,除了我在尝试删除文件时收到IOException,因为它们被另一个进程使用。

Here is the code I use to merge the files: 这是我用来合并文件的代码:

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

And here is the code for deleting the files: 以下是删除文件的代码:

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

Any assistance would be greatly appreciated. 任何帮助将不胜感激。 I presume somewhere in the loop when I'm merging the documents, something isn't being closed (reader/writer) but I've tried lots of different combos and nothing seems to work. 当我合并文档时,我假设在循环中的某个地方,某些东西没有被关闭(读者/作者)但我尝试了许多不同的组合,似乎没有任何工作。 It's REALLY starting to annoy me. 它真的开始惹恼我了。

UPDATE Thanks for your comments, everyone. 更新感谢您的评论,每个人。 I've amended my code to this: 我把我的代码修改为:

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

It compiles, but I get an error at runtime which points to the closing brace of the Using loop: 它编译,但我在运行时得到一个错误指向Using循环的右括号:

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

You're not disposing any of your resources. 你没有处置任何资源。

PdfReader , PdfWriter , and FileStream all implement IDisposable . PdfReaderPdfWriterFileStream都实现了IDisposable These all need to either be Dispose d or wrapped in a using block (preferably the latter). 这些都需要Dispose d或包裹在using块(最好是后者)中。

My guess is it's the PdfReader instances that are holding those files open. 我的猜测是将这些文件打开的PdfReader实例。

PS It's not enough to just Close them at the end of the method, as that will leave them open "permanently" (or as long as the process runs) if any exceptions occur before those calls execute. PS仅仅在方法结束时Close它们是不够的,因为如果在执行这些调用之前发生任何异常,它将使它们“永久”打开(或者只要进程运行)。 Either put your cleanup in a finally block or just use using . 要么把你清理的finally阻止或只是使用using

Although you're closing the document ( doc.Close(); ), you're not closing the filestream, writer and reader. 虽然您正在关闭文档( doc.Close(); ),但您并未关闭文件流,编写器和阅读器。

Add this after doc.Close(); doc.Close();之后添加doc.Close(); :

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM