开发者

Rename file using File.Move give IOException

I am writing a simple application that will rename JPEGs with the date/time they were taken before the current filename. This is so that I can combine all the photos that I took with those of my partner (different camera makes and filenames).

The following piece of code is where the failure occurs:

private void RenameFile(String oldFilename, String newFilename)
{
    if (File.Exists(oldFilename)
    {
        File.Move(oldFilename, newFilename);
    }
}

Example values: oldFilename = "E:\001.jpg" | newFilename = "E:\2009-08-07 06h05 -- 001.jpg"

The exception I am getting is:

System.IO.IOException was unhandled
  Message=The process cannot access the file because it is being used by another process.
  Source=mscorlib
  StackTrace:
       at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
       at System.IO.__Error.WinIOError()
       at System.IO.File.Move(String sourceFileName, String destFileName)
       at RenamePhotos.Form1.btnRenamePhotos_Click(Object sender, EventArgs e) in C:\Users\Neil Deadman\Desktop\RenamePhotos\RenamePhotos\Form1.cs:line 107
       at System.Windows.Forms.Control.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
       at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ButtonBase.WndProc(Message& m)
       at System.Windows.Forms.Button.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
       at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.Run(Form mainForm)
       at RenamePhotos.Program.Main() in C:\Users\Neil Deadman\Desktop\RenamePhotos\RenamePhotos\Program.cs:line 18
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()

If I use File.Copy instead then it works, but I have two files and can't delete the original and using File.Delete I get the sa开发者_JS百科me (or similar) exception.

During some tests, if I rename it to E:\a001.jpg then it seems to work?? The filename is valid as I can rename it using Windows Explorer. :S

Any ideas? The fact that some renames work seems to say it isn't a locking issue?

Cheers Neil


See File.Move on MSDN.

Specifically You cannot use the Move method to overwrite an existing file.


Thanks to everyone who posted. I managed to get it working with the following method

private void RenameFile(String oldFilename, String newFilename)
{
    FileInfo file = new FileInfo(oldFilename);

    if (file.Exists)
    {
        File.Move(oldFilename, newFilename);
    }
}

Strangely, my original didn't work but the above did.

The real issue was that I was debugging the code which still causes the IOException to be thrown. If I run the built application, it works fine!

Thanks Again! I just couldn't believe it when it would let me rename to certain names... must have been seeing things!

Neil


The fact that some renames work seems to say that it is not an external locking issue, but maybe in your program. If you put a breakpoint on File.Move(oldFilename, newFilename); can you still rename it from explorer?


private  bool IsFileLocked(string filename)
{
    FileInfo file = new FileInfo(filename);
    FileStream stream = null;

    try
    {
        stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
    }
    catch (IOException)
    {
        return true;
    }
    finally
    {
        if (stream != null)
            stream.Close();
    }

    //file is not locked
    return false;
}
public void MoveFile(string from, string to)
{
    try
    {
        FileInfo file = new FileInfo(from);
        // check if the file exists

        if (file.Exists)
        {
            // check if the file is not locked
            if (IsFileLocked(from) == false)
            {
                // move the file
                File.Move(from, to);
            }
        }
    }
    catch (Exception e)
    {
        ;
    }
}


There is another process, or maybe your own process currently using the file. This will prevent the file from being removed, but it will not prevent it from being copied. Most likely, your program opened the file but forgot to close it.


Two possibilities:

  1. The source file really is being held open by another app. In my experience, lots of Windows applications leave files open for longer than they should. Windows Explorer is probably the worst offender in this regard. I recommend you look at the Process Explorer and Process Monitor utilities from Microsoft SysInternals.

  2. The destination file already exists. You should check for that in your method as well as checking the source file.


The exception indicates that the file is in use - this could be by the application itself, i.e. are you creating/opening the file elsewhere and not closing it?

Another option is that the file is open for editing in another program and hasn't been closed.

You can use FileMon to check who owns the lock on the file.


File is probably still in use by some process on your system, most likely your program. You can use Process Explorer to check which process is using the file, and go further from there.


I got this error when I misinterpreted the File.Move documentation ("Moves a specified file to a new location, providing the option to specify a new file name") to mean that if you only specify the destination directory and not a new file name, it would work. Of course it does not; you must specify not only a new directory but also the file name, even if it's the same as the source. I have no idea why that mistake got turned into "being used by another process" though.


Renaming a file to the same name will give this error.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜