Skip to main content
 首页 » 编程设计

关闭后立即从 Web 服务器删除文件的 C# 技术

2024年01月22日30mfryf

我正在 C# MVC 应用程序中创建 PDF 发票,我将其附加到电子邮件并发送,理想情况下,一旦电子邮件发送完毕,我想删除发票以释放服务器空间并提高隐私/安全性.我已经编写了代码来执行此操作,但它有 50% 的时间会失败,因为该文件被另一个进程锁定(我不确定是创建/写入进程锁定了它还是电子邮件发送)。我正在异步发送电子邮件(即要删除的代码在电子邮件发送之前不会执行)。

如果我能提供一些有关如何处理此问题的提示,我将不胜感激。我可以运行一个作业来清理旧文件,但我更愿意边走边清理它们...

我忘了提到我正在使用 iTextSharp 生成 PDF - 关键是这段代码用于生成最终发票(我能够删除作为参数传入的文件列表而没有戏剧性):

/// <summary> 
        /// http://stackoverflow.com/questions/4276019/itextsharp-pdfcopy-use-examples 
        /// </summary> 
        /// <param name="fileNames"></param> 
        /// <param name="outFile"></param> 
        private void CombineMultiplePDFs(List<string> files, string outFile) 
        { 
            int pageOffset = 0; 
            int f = 0; 
 
            iTextSharp.text.Document document = null; 
            PdfCopy writer = null; 
 
            foreach (string file in files) 
            { 
                // we create a reader for a certain document 
                PdfReader reader = new PdfReader(file); 
                reader.ConsolidateNamedDestinations(); 
                // we retrieve the total number of pages 
                int n = reader.NumberOfPages; 
 
                pageOffset += n; 
 
                if (f == 0) 
                { 
                    // step 1: creation of a document-object 
                    document = new iTextSharp.text.Document(reader.GetPageSizeWithRotation(1)); 
                    // step 2: we create a writer that listens to the document 
                    writer = new PdfCopy(document, new FileStream(outFile, FileMode.Create)); 
                    // step 3: we open the document 
                    document.Open(); 
                } 
                // step 4: we add content 
                for (int i = 0; i < n; ) 
                { 
                    ++i; 
                    if (writer != null) 
                    { 
                        PdfImportedPage page = writer.GetImportedPage(reader, i); 
                        writer.AddPage(page); 
                    } 
                } 
                PRAcroForm form = reader.AcroForm; 
 
                if (form != null && writer != null) 
                { 
                    writer.CopyAcroForm(reader); 
                } 
 
                f++; 
            } 
 
            // step 5: we close the document 
            if (document != null) 
            { 
                document.Close(); 
            } 
        } 

然后 PDF 文件位于服务器上(例如“~/Invoices/0223.pdf”),准备附加到电子邮件中,如下所示:

MailMessage mailMessage = new MailMessage(); 
        mailMessage.From = new MailAddress(WebConfig.GetWebConfigKey(AppSettingsKey.ReplyEmailAddress.ToString())); 
        mailMessage.To.Add(new MailAddress(user.Email)); 
        mailMessage.Subject = emailTemplate.TemplateSubject; 
        mailMessage.Body = emailTemplate.TemplateContent; 
        mailMessage.IsBodyHtml = false; 
        mailMessage.Attachments.Add(new Attachment(HttpContext.Current.Server.MapPath("/Invoices/" + invoiceId + ".pdf"))); 
 
        SmtpClient client = new SmtpClient(); 
 
        try 
        { 
            client.Send(mailMessage); 
        } 
        catch{...}{ 
            //Error handling 
        } 
 
        client.Dispose(); 

然后我尝试删除它:

File.Delete(HttpContext.Current.Server.MapPath("/Invoices/" + invoiceId + ".pdf")); 

请您参考如下方法:

与其将文件保存到磁盘并引发性能、IO 和删除问题,不如查看您的 PDF 和邮件库是否支持将 PDF 写入 MemoryStream,并将该流附加到电子邮件。