Share via


File.Move and/or File.Copy file locked

Question

Friday, June 5, 2015 4:11 PM

I have a .pdf in a folder that I'm moving to a dated directory, however the .net 3.5 console application says it's locked.  The .pdf was copied there manually by me to a local drive and there can't be locked.  It's not been open by anything else and when VS2013 is not running I can move the file manually, happens with any .pdf in this directory. 

My code seems to be locking itself. Any ideas? 

All replies (9)

Monday, June 8, 2015 9:07 AM âś…Answered

For anyone reading in future this is the problem/resolution. 

A MaiMessage object was being created with this file as an attachment, this was *not* being done inside a using statement and therefore not being disposed of.  I changed the code to use a using() and all is fine. 


Friday, June 5, 2015 5:39 PM | 1 vote

What folder are you trying to access and what rights is your applicatin running under?

Could it be your own code already opened the file before and did not properly dispose of it's Handle?

Please give us your full code in proper code-blocks.

Also see dipose pattern and proper error handling and handling of File Handles:

Dispose Pattern (and Finalize)

Exception Handling Best Practices in .NET - CodeProject


Monday, June 8, 2015 7:05 AM

Hi,

Before File.Move &&File.Copy method, have you disposed of your streams to collect garbage to clean up.

For example, I suspect the problem is that the filestream isn't being garbage collected when you need it to:

using (FileStream fs = new FileStream("C:\myTempDirectory\myFile.doc", FileMode.OpenOrCreate, FileAccess.Write)) 
{
    BinaryWriter br = new BinaryWriter(fs); 
    br.Write("BinaryDataFromDB"); 
    fs.Flush(); 
    fs.Close(); // dispose FileStream
}

// Copy file 
File.Copy(sourceFileName, destinationFilename, true);

Best regards,

Kristin

We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
Click HERE to participate the survey.


Monday, June 8, 2015 8:40 AM

Hi, 

I'm not using filestream and I'm not creating these files in my C# program.  They exist as .pdf files 

on disk created by another process. 

The logic is as follows: 

  • Read all files to be processed into a List<string> 
  • Loop thru the list and perform some data lookups based upon name
  • Move the .pdf to one of two folders (\ok or \error) folder.  

The .pdf file is not created, modified or opened in any way.  All I'm trying to do is move it to 

one of two directories.   I have tried both copy & move as my original example shows.

Thanks  


Monday, June 8, 2015 8:45 AM

Right so the problem is that the file is being emailed using StmpClient just before this attempt to move/copy is initiated.  The file I'm attempting to move is being attached but seems to still be locked my the emailing process. If I comment out the call to the SendMail method all is good.  

So, follow up question.  How do I pause until SmtpClient has finished with the file?  

After pasting in this code the command using() jumped out at me.  I'm going to try this because it might be the email stuff is not being disposed off. 

internal void SendMail(SettingsEntity se, String toAddress, String accountCode, ref Byte[] picture, String pdf)
        {
            MailMessage message = new MailMessage();
            String body = string.Empty;
            Stream stream = null;

            message.From = new MailAddress(se.FromAddress);
            message.To.Add(new MailAddress(toAddress));
            message.Subject = String.Format(@"{0} - ({1})", se.SubjectText, accountCode);

            // Add the PDf. 
            if (File.Exists(pdf))
            {
                message.Attachments.Add(new Attachment(pdf));
            }


            // Add the signature (if exists) as an inline image. 
            if (picture != null)
            {
                stream = new MemoryStream(picture);
                if (stream != null)
                {
                    var image = new LinkedResource(stream);

                    image.ContentId = Guid.NewGuid().ToString();

                    body = string.Format(@" <img src=""cid:{0}"" />", image.ContentId);
                    AlternateView view = AlternateView.CreateAlternateViewFromString(body, null, "text/html");
                    view.LinkedResources.Add(image);
                    message.AlternateViews.Add(view);
                }
            }
            else
            {
                message.Body = "Your Statement is attached.";
            }

            message.IsBodyHtml = false;
            message.Priority = MailPriority.Normal;

            SmtpClient client = new SmtpClient(se.SmtpServer);

            client.Send(message);
        }

Monday, June 8, 2015 9:04 AM | 1 vote

According to the Documentation, Send() is a blocking call as is expected of it. Even one of those without a default timeout (so it might block indenfinitely becasue it just keeps trying).
You would have to go out of your way to put it into a background thread to cause a race condition. In wich case you have not shown us the relevant code parts (the multithreading).

Thanks to the JIT it can also be that without the Send most of the code (inlcuding the real culptript) is never executed. So it can appear as if Send was the cause, when it is not. When it was some other code 4 functiosn further up that provides the data for the function.

Where do you get that "ref Byte[] picture" Argument? From the disk?

I also noticed your PDf attachment code is wrong. The Attachment constrcutor you use attaches a String, NOT the file at a path specified by that string.
Or you check is faulty, because you are running a Exists test on the conents of a pdf, rather then it's path.


Monday, June 8, 2015 9:55 AM | 1 vote

@The real Slartibartfast

Glad to know you solved this problem and thanks for sharing your solution.

Please mark your reply and close this thread.

Have a nice day!

Kristin

We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
Click HERE to participate the survey.


Monday, June 8, 2015 10:40 AM

Where do you get that "ref Byte[] picture" Argument? From the disk?

Yes that Byte[] is updated once, from disk at runtime.  I was having issues when storing in a stream (it needed resetting) so I stored in an array and converted each time I need it. 


Monday, June 8, 2015 10:44 AM

I also noticed your PDf attachment code is wrong. The Attachment constrcutor you use attaches a String, NOT the file at a path specified by that string.
Or you check is faulty, because you are running a Exists test on the conents of a pdf, rather then it's path.

I don't really understand what you are saying.  The String pdf has been validated as an existing file, both File.Exists() and Attachment() take String as a parameter.