File.Create и File.OpenWrite не освобождают файл, даже если он закрыт и также удален - PullRequest
0 голосов
/ 17 октября 2019

Я загружаю файл pdf с использованием объекта HttpWebRequest и записываю содержимое непосредственно в FileStream из потока ответов, используя все блоки «using», а также метод .Close сразу после копирования данных. И следующим шагом мне нужно извлечь некоторый текст из этого pdf-файла с помощью какой-либо сторонней библиотеки (iText7), но он не может получить доступ к файлу. Сначала я думал, что это проблема, связанная с iText7, но потом понял, что это не так, потому что я даже не могу удалить файл из проводника, получая ошибку «файл используется» моим собственным приложением.

Вот пример кода:

            HttpWebRequest webReq = (HttpWebRequest)HttpWebRequest.Create(url);
            webReq.AllowAutoRedirect = true;
            webReq.CookieContainer = Cookies;
            webReq.UserAgent = UserAgent;
            webReq.Referer = Referrer;
            webReq.Method = WebRequestMethods.Http.Get;

            using (HttpWebResponse response = (HttpWebResponse)webReq.GetResponse())
            {
                using (Stream httpResponseStream = response.GetResponseStream())
                {
                    using (FileStream output = File.Create(file1))
                    {
                        httpResponseStream.CopyTo(output);
                        output.Close();
                    }
                    httpResponseStream.Close();
                    response.Close();

                    Cookies = webReq.CookieContainer;
                }
            }

            GC.Collect();

            ExtractPDFDoc(file1);//error throws in this function and the exception.message is "Cannot open document."

            Console.WriteLine("now waiting to let you check the file is in use? try delete it manually...");
            Console.ReadKey(); //added this line to ensure that file is actually in use. I can't even delete the file manually from windows file explorer at this time. But, interestingly, Acrobat Reader can OPEN the file when I double click, which makes me thing that Adobe and iText7 uses different methods to open the pdf file - but anyway - I can't help it tho.

Не могли бы вы помочь, что здесь не так?

Для тех, кто хочет увидеть метод ExtractPDFDoc ():

public static object ExtractPDFDoc(string filename)
    {

        iText.Kernel.Pdf.PdfReader pdfReader = null;
        iText.Kernel.Pdf.PdfDocument pdfDocument = null;


        try
        {

            pdfReader = new iText.Kernel.Pdf.PdfReader(filename);

            pdfDocument = new iText.Kernel.Pdf.PdfDocument(pdfReader);

        }
        catch (Exception ex)
        {

            pdfReader = null;
            pdfDocument = null;

            return new Exception(string.Format("ExtractPDFDoc() failed on file '{0}' with message '{1}'", filename, ex.Message));

            //this is where I get the error, ex.Message is 'Cannot open document.'
            //however, I can open it in Adobe Reader but I can't delete it before closing my app.
        }
}

Ответы [ 2 ]

1 голос
/ 17 октября 2019

Если я правильно помню, все объекты iText являются IDisposable, поэтому вы должны быть уверены, что избавились от них. Кроме того, я не знаю, почему вы возвращаете исключение вместо того, чтобы просто выбросить его.

public static object ExtractPDFDoc(string filename)
{
    iText.Kernel.Pdf.PdfReader pdfReader = null;
    iText.Kernel.Pdf.PdfDocument pdfDocument = null;

    try
    {
        pdfReader = new iText.Kernel.Pdf.PdfReader(filename);
        pdfDocument = new iText.Kernel.Pdf.PdfDocument(pdfReader);
    }
    catch (Exception ex)
    {
        throw new Exception(string.Format("ExtractPDFDoc() failed on file '{0}' with message '{1}'", filename, ex.Message), ex);
    }
    finally
    {
        pdfReader?.Dispose();
        pdfDocument?.Dispose();
    }
}

Вне зависимости от этого, вы также можете составлять ваши операторы использования вместо их вложения.

using (HttpWebResponse response = (HttpWebResponse)webReq.GetResponse())
using (Stream httpResponseStream = response.GetResponseStream())
using (FileStream output = File.Create(file1))
{
     // do stuff
}
0 голосов
/ 18 октября 2019

Мне очень жаль, благодаря @howcheng, я понял, что это был iText7, который оставляет файл открытым после того, как ему не удалось открыть документ из-за того, что один из его файлов зависимостей отсутствовал в выходной папке.

Понятно, что я должен сделать .Close() для объектов iText7 в исключительных случаях, чтобы избежать ложных представлений, подобных этому.

Спасибо за вашу помощь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...