Невозможно удалить файл из-за исключения IOException. Он используется другим процессом

Я продолжаю получать вышеуказанную ошибку при попытке удалить файл. См. комментарий к коду, чтобы точно знать, где возникает ошибка.

foreach (string file in supportedFiles)
{
    if (file.EndsWith(".pdf"))
    {
        PDFImageExtractor.ExtractImagesFromPDF(
            file, 
            AppVars.TempFolder, 
            Path.GetFileNameWithoutExtension(file));
    }
}

foreach (string file in supportedFiles)
{
    if (file.EndsWith(".pdf"))
    {
        // I get the error here. 
        File.Delete(file);
    }
}

Вот код до ошибки в методе PDFImageExtractor.ExtractImagesFromPDF:

public static void ExtractImagesFromPDF(
    string sourcePdf, 
    string outputPath, 
    string fileName)
{
    // NOTE: This will only get the first image it finds per page.
    PdfReader pdf = new PdfReader(sourcePdf);
    RandomAccessFileOrArray raf = 
        new iTextSharp.text.pdf.RandomAccessFileOrArray(sourcePdf);

    try
    {
        for (int pageNumber = 1; pageNumber <= pdf.NumberOfPages; pageNumber++)
        {
            PdfDictionary pg = pdf.GetPageN(pageNumber);
            PdfDictionary res = (PdfDictionary)PdfReader.GetPdfObject(pg.Get(PdfName.RESOURCES));
            PdfDictionary xobj = (PdfDictionary)PdfReader.GetPdfObject(res.Get(PdfName.XOBJECT));

            if (xobj != null)
            {
                foreach (PdfName name in xobj.Keys)
                {
                    PdfObject obj = xobj.Get(name);
                    if (obj.IsIndirect())
                    {
                        PdfDictionary tg = (PdfDictionary)PdfReader.GetPdfObject(obj);
                        PdfName type = 
                            (PdfName)PdfReader.GetPdfObject(tg.Get(PdfName.SUBTYPE));

                        if (PdfName.IMAGE.Equals(type))
                        {
                            int XrefIndex = Convert.ToInt32(((PRIndirectReference)obj).Number.ToString(CultureInfo.InvariantCulture));
                            PdfObject pdfObj = pdf.GetPdfObject(XrefIndex);
                            PdfStream pdfStrem = (PdfStream)pdfObj;
                            byte[] bytes = PdfReader.GetStreamBytesRaw((PRStream)pdfStrem);
                            if ((bytes != null))
                            {
                                using (MemoryStream memStream = new MemoryStream(bytes))
                                {
                                    memStream.Position = 0;
                                    System.Drawing.Image img = System.Drawing.Image.FromStream(memStream);
                                    // must save the file while stream is open.
                                    if (!Directory.Exists(outputPath))
                                        Directory.CreateDirectory(outputPath);

                                    string path = Path.Combine(outputPath, String.Format(@"{0}.jpg", fileName));

                                    using (EncoderParameters parms = new EncoderParameters(1))
                                    {
                                        parms.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Compression, 0);
                                        // GetImageEncoder is found below this method
                                        ImageCodecInfo jpegEncoder = GetImageEncoder("JPEG");
                                        img.Save(path, jpegEncoder, parms);
                                    }

                                    //EncoderParameters parms = new EncoderParameters(1);

                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
    finally
    {
        pdf.Close();
    }
}

public static ImageCodecInfo GetImageEncoder(string imageType)
{
    imageType = imageType.ToUpperInvariant();

    foreach (ImageCodecInfo info in ImageCodecInfo.GetImageEncoders())
    {
        if (info.FormatDescription == imageType)
        {
            return info;
        }
    }
    return null;
}

Я где-то пропустил использование!?


person RJ.    schedule 23.08.2012    source источник
comment
Зачем вам нужен iTextSharp.text.pdf.RandomAccessFileOrArray(raf)? Может надо закрыть?   -  person Amiram Korach    schedule 24.08.2012
comment
это было все. ты да человек!   -  person RJ.    schedule 24.08.2012


Ответы (2)


Переменная "raf" не используется и не закрывается. Он блокирует файл.

RandomAccessFileOrArray raf = 
        new iTextSharp.text.pdf.RandomAccessFileOrArray(sourcePdf);
person Amiram Korach    schedule 23.08.2012

Я думаю, что ваш:

System.Drawing.Image img = System.Drawing.Image.FromStream(memStream);

Отсутствует использование.

Реализуют ли PdfReader или RandomAccessFileOrArray IDisposable?

Вероятно, глупо, но, возможно, стоит использовать Process Explorer, чтобы увидеть, есть ли у кого-нибудь еще дескриптор файлов.

person Cashley    schedule 23.08.2012
comment
только что добавил использование к этому. я думаю может быть оно. - person RJ.; 24.08.2012
comment
они не реализуют одноразовые - person RJ.; 24.08.2012
comment
Являются ли вызовы библиотеки PDF точно синхронными? Если вы не уверены, вы можете поставить грубую силу Thread.Sleep(60000) или что-то еще перед вызовом File.Delete просто для проверки. Хоть сейчас еще раз посмотри. :) - person Cashley; 24.08.2012
comment
спасибо, ребята, но Амирам Корах понял это. мне нужно было закрыть iTextSharp.text.pdf.RandomAccessFileOrArray (raf). :) - person RJ.; 24.08.2012
comment
Попробуйте добавить raf.Close() в свой наконец? (извините, это просто просмотр некоторых документов iText) - person Cashley; 24.08.2012