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

C#PDF删除-文件';被另一个进程使用';,c#,pdf,itextsharp,ioexception,delete-file,C#,Pdf,Itextsharp,Ioexception,Delete File,我到处寻找这个问题的答案。我知道收到异常的原因,但我无法在我的代码中找到导致异常的原因 基本上,我的代码创建了四个单独的PDF文件,将它们合并到一个大的PDF文件中,然后删除原来的四个文件。一切都很好,除了我在尝试删除文件时收到IOException,因为它们“正在被另一个进程使用” 以下是我用于合并文件的代码: private static Document MergeFiles(string[] fileNames, string finalFileName) { Document

我到处寻找这个问题的答案。我知道收到异常的原因,但我无法在我的代码中找到导致异常的原因

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

虽然您正在关闭文档(
doc.Close();
),但并没有关闭文件流、写入程序和读取器

将此添加到
doc.Close()之后


虽然您正在关闭文档(
doc.Close();
),但并没有关闭文件流、写入程序和读取器

将此添加到
doc.Close()之后

你没有处理你的任何资源

PdfReader
PdfWriter
FileStream
都实现了
IDisposable
。所有这些都需要
Dispose
d,或者使用
块(最好是后者)包装在

我猜是
PdfReader
实例打开了这些文件

另外,仅仅在方法末尾关闭它们是不够的,因为如果在这些调用执行之前发生任何异常,它们将“永久”打开(或者只要流程运行)。要么将清理放在
finally
块中,要么使用
using

即可,这样就不会处理任何资源

PdfReader
PdfWriter
FileStream
都实现了
IDisposable
。所有这些都需要
Dispose
d,或者使用
块(最好是后者)包装在

我猜是
PdfReader
实例打开了这些文件


另外,仅仅在方法末尾关闭它们是不够的,因为如果在这些调用执行之前发生任何异常,它们将“永久”打开(或者只要流程运行)。或者将清理放在
finally
块中,或者只使用
using

或者在using语句中实例化PdfReader(fileName[a])?以下几点建议:不要返回
文档
对象,一旦关闭它,它就没有意义了。返回一个布尔值表示成功,返回文件名(可能不是因为您正在传入它),或者可能切换到
MemoryStream
并返回字节数组。如果您原来的四个文档足够小,我也会将它们创建为一个
MemoryStream
,并且只处理字节数组。这样你就不必担心碰到磁盘了。Chris,我最终使用了你的解决方案,使用了MemorySteam和字节数组。它最终变得更快、更容易,没有任何与PDF阅读器相关的问题。谢谢你的建议!也许可以在using语句中实例化PdfReader(fileName[a])?有几点建议:不要返回
文档
对象,一旦关闭它就没有意义了。返回一个布尔值表示成功,返回文件名(可能不是因为您正在传入它),或者可能切换到
MemoryStream
并返回字节数组。如果您原来的四个文档足够小,我也会将它们创建为一个
MemoryStream
,并且只处理字节数组。这样你就不必担心碰到磁盘了。Chris,我最终使用了你的解决方案,使用了MemorySteam和字节数组。它最终变得更快、更容易,没有任何与PDF阅读器相关的问题。谢谢你的建议!非常感谢,亚伦。您能否提供一个快速示例,说明我如何在这个实例中实例化using语句?我是使用语句的新手(从昨天开始!):)对不起,我应该澄清一下。我知道使用该语句的一般方法,但我不确定在这个例子中如何使用它。例如,我已完成“使用(PDFReader reader=new PDFReader(文件名[0])){//code}”,但我收到一个编译错误“无法分配给reader,因为它是using块内此行的“using变量”:“reader=new PDFReader(文件名[a]);”@BennyO'Neill,关于您最近的编辑,请尝试在
doc.Close
之前设置
writer.CloseStream=false
。嗨,伙计,这也不起作用。我怀疑大会本身有问题。我对您的所有建议(以及MSDN论坛上的其他一些建议)进行了大量调整,并创建了一个完全可行的解决方案,但不断抛出一个毫无意义的异常。不管怎么说,上面有人建议使用我已经做过的字节数组,现在它似乎工作得完美无缺。谢谢你的帮助和建议!非常感谢,亚伦。您能否提供一个快速示例,说明我如何在这个实例中实例化using语句?我是使用语句的新手(从昨天开始!):)对不起,我应该澄清一下。我知道使用该语句的一般方法,但我不确定在这个例子中如何使用它。例如,我已完成“使用(PDFReader reader=new PDFReader(文件名[0])){//code}”,但我收到一个编译错误“无法分配给reader,因为它是using块内此行的“using变量”:“reader=new PDFReader(文件名[a]);”@BennyO'Neill,关于您最近的编辑,请尝试在
doc.Close
之前设置
writer.CloseStream=false
。嗨,伙计,这也不起作用。我怀疑大会本身有问题。我对您的所有建议(以及MSDN论坛上的其他一些建议)进行了大量调整,并创建了一个完全可行的解决方案,但在那一天不断抛出一个异常
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.
writer.Close();
output.Close();
reader.Close();