简体   繁体   中英

How can I get File.Delete() to actually delete my file?

I generate a PDF file, save it on the server:

var bytes = ms.ToArray();
. . .
String fileFullpath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), pdfFileName);
. . .
File.WriteAllBytes(fileFullpath, bytes);

...and then save it into a Sharepoint Document Library, and send it as an email attachment to the person who generated the file:

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);

...at which point, I no longer need the file I saved to disk on the server, and so, as shown in the last line above, attempt to delete it.

However, it doesn't work. The now-redundant file is still in the place where it was saved.

Why, and how can I get it to understand that "Delete" really means "delete"?

UPDATE

Here are the methods Scott wanted to see:

// This works; got it from Henry Zucchini's answer at http://stackoverflow.com/questions/468469/how-do-you-upload-a-file-to-a-document-library-in-sharepoint
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();
}

UPDATE 2

I see when stepping through it, after adding this test:

if (File.Exists(fileFullpath))
{
    File.Delete(fileFullpath);
}

...that there is an exception after all, in the IOException catch block:

The process cannot access the file 'C:\\Users\\TEMP.SP.018\\Desktop\\DirectPayDynamic_2015Jul28_19_02_clayshan_0.pdf' because it is being used by another process.

So how is one of the other methods holding onto it? ISTM that SavePDFToDocumentLibrary() is safe, because it uses using blocks.

Is data.Dispose(); in SendEmailWithAttachment() not enough? Do I need to explicitly call close there, or what?

UPDATE 3

I added "message.Dispose();" just prior to "data.Dispose();" in SendEmailWithAttachment(), but it made no difference.

Try disposing the file stream used in SavePDFToDocumentLibrary like so:

using (FileStream fileStream = File.OpenRead(fileToUpload))
{
    ...
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM