我怎样才能让 File.Delete() 真正删除我的文件?
How can I get File.Delete() to actually delete my file?
我生成一个 PDF 文件,保存在服务器上:
var bytes = ms.ToArray();
. . .
String fileFullpath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), pdfFileName);
. . .
File.WriteAllBytes(fileFullpath, bytes);
...然后将其保存到 Sharepoint 文档库中,并将其作为电子邮件附件发送给生成文件的人:
SavePDFToDocumentLibrary(fileFullpath);
String from = GetFromEmailID();
String to = GetUserEmail();
String subjLine = String.Format("The PDF file you generated ({0})", pdfFileName);
String body = String.Format("The Direct Pay PDF file you generated ({0}) is attached.", pdfFileName);
SendEmailWithAttachment(fileFullpath, from, to, subjLine, body);
// Now that it has been put in a Document Library and emailed, delete the file that was saved locally
File.Delete(fileFullpath);
...此时,我不再需要我保存到服务器磁盘上的文件,因此,如上面最后一行所示,尝试删除它。
但是,它不起作用。现在冗余的文件仍在保存的地方。
为什么,我怎样才能理解 "Delete" 真正意味着 "delete"?
更新
以下是 Scott 希望看到的方法:
// This works; got it from Henry Zucchini's answer at
private void SavePDFToDocumentLibrary(String fullpath)
{
String fileToUpload = fullpath;
String sharePointSite = siteUrl;
String documentLibraryName = "DirectPayPDFForms";
using (SPSite oSite = new SPSite(sharePointSite))
{
using (SPWeb oWeb = oSite.OpenWeb())
{
if (!System.IO.File.Exists(fileToUpload))
throw new FileNotFoundException("File not found.", fileToUpload);
SPFolder doclib = oWeb.Folders[documentLibraryName];
// Prepare to upload
Boolean replaceExistingFiles = true;
String fileName = System.IO.Path.GetFileName(fileToUpload);
FileStream fileStream = File.OpenRead(fileToUpload);
// Upload document
SPFile spfile = doclib.Files.Add(fileName, fileStream, replaceExistingFiles);
// Commit
doclib.Update();
}
}
}
// This is adapted from https://msdn.microsoft.com/en-us/library/system.net.mail.mailmessage(v=vs.90).aspx
public static void SendEmailWithAttachment(string fileToMail, String from, String to, String subj, String body)
{
String server = GetSMTPHostName(); //"468802-DEV-SPWF"; // change this to prod when go live, or programatically assign?
// Specify the file to be attached and sent.
string file = fileToMail;
// Create a message and set up the recipients.
MailMessage message = new MailMessage(
from,
to,
subj,
body);
// Create the file attachment for this e-mail message.
Attachment data = new Attachment(file, MediaTypeNames.Application.Octet);
// Add time stamp information for the file.
ContentDisposition disposition = data.ContentDisposition;
disposition.CreationDate = System.IO.File.GetCreationTime(file);
disposition.ModificationDate = System.IO.File.GetLastWriteTime(file);
disposition.ReadDate = System.IO.File.GetLastAccessTime(file);
// Add the file attachment to this e-mail message.
message.Attachments.Add(data);
//Send the message.
SmtpClient client = new SmtpClient(server);
// Add credentials if the SMTP server requires them.
client.Credentials = CredentialCache.DefaultNetworkCredentials;
try
{
client.Send(message);
}
catch (Exception ex)
{
Console.WriteLine("Exception caught in CreateMessageWithAttachment(): {0}", ex.ToString());
}
// Display the values in the ContentDisposition for the attachment.
// May not need/want this section
ContentDisposition cd = data.ContentDisposition;
Console.WriteLine("Content disposition");
Console.WriteLine(cd.ToString());
Console.WriteLine("File {0}", cd.FileName);
Console.WriteLine("Size {0}", cd.Size);
Console.WriteLine("Creation {0}", cd.CreationDate);
Console.WriteLine("Modification {0}", cd.ModificationDate);
Console.WriteLine("Read {0}", cd.ReadDate);
Console.WriteLine("Inline {0}", cd.Inline);
Console.WriteLine("Parameters: {0}", cd.Parameters.Count);
foreach (DictionaryEntry d in cd.Parameters)
{
Console.WriteLine("{0} = {1}", d.Key, d.Value);
}
// </ May not need/want this section
data.Dispose();
}
更新 2
我在添加此测试后单步执行时看到:
if (File.Exists(fileFullpath))
{
File.Delete(fileFullpath);
}
...毕竟 是 一个异常,在 IOException catch 块中:
进程无法访问文件 'C:\Users\TEMP.SP.018\Desktop\DirectPayDynamic_2015Jul28_19_02_clayshan_0.pdf',因为它正被另一个进程使用。
那么其他方法之一是如何坚持下去的呢? ISTM 认为 SavePDFToDocumentLibrary() 是安全的,因为它使用 using 块。
是data.Dispose();在 SendEmailWithAttachment() 中还不够吗?我需要在那里明确调用 close 还是什么?
更新 3
我在 SendEmailWithAttachment() 中的 "data.Dispose();" 之前添加了 "message.Dispose();",但没有任何区别。
尝试像这样处理 SavePDFToDocumentLibrary
中使用的文件流:
using (FileStream fileStream = File.OpenRead(fileToUpload))
{
...
}
我生成一个 PDF 文件,保存在服务器上:
var bytes = ms.ToArray();
. . .
String fileFullpath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), pdfFileName);
. . .
File.WriteAllBytes(fileFullpath, bytes);
...然后将其保存到 Sharepoint 文档库中,并将其作为电子邮件附件发送给生成文件的人:
SavePDFToDocumentLibrary(fileFullpath);
String from = GetFromEmailID();
String to = GetUserEmail();
String subjLine = String.Format("The PDF file you generated ({0})", pdfFileName);
String body = String.Format("The Direct Pay PDF file you generated ({0}) is attached.", pdfFileName);
SendEmailWithAttachment(fileFullpath, from, to, subjLine, body);
// Now that it has been put in a Document Library and emailed, delete the file that was saved locally
File.Delete(fileFullpath);
...此时,我不再需要我保存到服务器磁盘上的文件,因此,如上面最后一行所示,尝试删除它。
但是,它不起作用。现在冗余的文件仍在保存的地方。
为什么,我怎样才能理解 "Delete" 真正意味着 "delete"?
更新
以下是 Scott 希望看到的方法:
// This works; got it from Henry Zucchini's answer at
private void SavePDFToDocumentLibrary(String fullpath)
{
String fileToUpload = fullpath;
String sharePointSite = siteUrl;
String documentLibraryName = "DirectPayPDFForms";
using (SPSite oSite = new SPSite(sharePointSite))
{
using (SPWeb oWeb = oSite.OpenWeb())
{
if (!System.IO.File.Exists(fileToUpload))
throw new FileNotFoundException("File not found.", fileToUpload);
SPFolder doclib = oWeb.Folders[documentLibraryName];
// Prepare to upload
Boolean replaceExistingFiles = true;
String fileName = System.IO.Path.GetFileName(fileToUpload);
FileStream fileStream = File.OpenRead(fileToUpload);
// Upload document
SPFile spfile = doclib.Files.Add(fileName, fileStream, replaceExistingFiles);
// Commit
doclib.Update();
}
}
}
// This is adapted from https://msdn.microsoft.com/en-us/library/system.net.mail.mailmessage(v=vs.90).aspx
public static void SendEmailWithAttachment(string fileToMail, String from, String to, String subj, String body)
{
String server = GetSMTPHostName(); //"468802-DEV-SPWF"; // change this to prod when go live, or programatically assign?
// Specify the file to be attached and sent.
string file = fileToMail;
// Create a message and set up the recipients.
MailMessage message = new MailMessage(
from,
to,
subj,
body);
// Create the file attachment for this e-mail message.
Attachment data = new Attachment(file, MediaTypeNames.Application.Octet);
// Add time stamp information for the file.
ContentDisposition disposition = data.ContentDisposition;
disposition.CreationDate = System.IO.File.GetCreationTime(file);
disposition.ModificationDate = System.IO.File.GetLastWriteTime(file);
disposition.ReadDate = System.IO.File.GetLastAccessTime(file);
// Add the file attachment to this e-mail message.
message.Attachments.Add(data);
//Send the message.
SmtpClient client = new SmtpClient(server);
// Add credentials if the SMTP server requires them.
client.Credentials = CredentialCache.DefaultNetworkCredentials;
try
{
client.Send(message);
}
catch (Exception ex)
{
Console.WriteLine("Exception caught in CreateMessageWithAttachment(): {0}", ex.ToString());
}
// Display the values in the ContentDisposition for the attachment.
// May not need/want this section
ContentDisposition cd = data.ContentDisposition;
Console.WriteLine("Content disposition");
Console.WriteLine(cd.ToString());
Console.WriteLine("File {0}", cd.FileName);
Console.WriteLine("Size {0}", cd.Size);
Console.WriteLine("Creation {0}", cd.CreationDate);
Console.WriteLine("Modification {0}", cd.ModificationDate);
Console.WriteLine("Read {0}", cd.ReadDate);
Console.WriteLine("Inline {0}", cd.Inline);
Console.WriteLine("Parameters: {0}", cd.Parameters.Count);
foreach (DictionaryEntry d in cd.Parameters)
{
Console.WriteLine("{0} = {1}", d.Key, d.Value);
}
// </ May not need/want this section
data.Dispose();
}
更新 2
我在添加此测试后单步执行时看到:
if (File.Exists(fileFullpath))
{
File.Delete(fileFullpath);
}
...毕竟 是 一个异常,在 IOException catch 块中:
进程无法访问文件 'C:\Users\TEMP.SP.018\Desktop\DirectPayDynamic_2015Jul28_19_02_clayshan_0.pdf',因为它正被另一个进程使用。
那么其他方法之一是如何坚持下去的呢? ISTM 认为 SavePDFToDocumentLibrary() 是安全的,因为它使用 using 块。
是data.Dispose();在 SendEmailWithAttachment() 中还不够吗?我需要在那里明确调用 close 还是什么?
更新 3
我在 SendEmailWithAttachment() 中的 "data.Dispose();" 之前添加了 "message.Dispose();",但没有任何区别。
尝试像这样处理 SavePDFToDocumentLibrary
中使用的文件流:
using (FileStream fileStream = File.OpenRead(fileToUpload))
{
...
}