File.Create 和 File.OpenWrite 不会释放文件,即使文件已关闭并已处置



我正在使用 HttpWebRequest 对象下载一个 pdf 文件,并使用所有"using"块以及 .复制数据后立即关闭方法。 下一步,我需要使用一些第三方库(iText7(从该pdf文件中提取一些文本,但它无法访问该文件。 起初,我以为是与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.
}
}

如果我没记错的话,iText 对象都是可识别的,所以你也应该确保处理它们。另外,我不知道你为什么要返回一个异常,而不仅仅是抛出它。

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 语句而不是嵌套它们。

using (HttpWebResponse response = (HttpWebResponse)webReq.GetResponse())
using (Stream httpResponseStream = response.GetResponseStream())
using (FileStream output = File.Create(file1))
{
// do stuff
}

我非常抱歉,多亏@howcheng,我意识到是 iText7 在无法打开文档后使文件保持打开状态,因为它的依赖项文件之一在输出文件夹中丢失。

很明显,我应该在异常时对 iText7 对象进行.Close(),以避免这样的错误看法。

感谢您的帮助。

相关内容

最新更新