C# 使用 File.Move 重命名文件给 IOException

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1868173/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 21:29:59  来源:igfitidea点击:

Rename file using File.Move give IOException

c#.net

提问by neildeadman

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

我正在编写一个简单的应用程序,它将使用在当前文件名之前拍摄的日期/时间重命名 JPEG。这样我就可以将我拍摄的所有照片与我伙伴的照片(不同的相机品牌和文件名)结合起来。

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"

示例值: 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 same (or similar) exception.

如果我使用 File.Copy 则它可以工作,但是我有两个文件并且无法删除原始文件并且使用 File.Delete 我得到相同(或类似)的异常。

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

在某些测试中,如果我将其重命名为 E:\a001.jpg 那么它似乎可以工作?文件名有效,因为我可以使用 Windows 资源管理器重命名它。:S

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

有任何想法吗?某些重命名工作的事实似乎表明这不是锁定问题?

Cheers Neil

尼尔干杯

采纳答案by neildeadman

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!

真正的问题是我正在调试仍然导致抛出 IOException 的代码。如果我运行构建的应用程序,它工作正常!

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

再次感谢!当它让我重命名为某些名称时,我简直不敢相信......一定是看到了东西!

Neil

尼尔

回答by monksy

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.

还有另一个进程,或者您自己的进程当前正在使用该文件。这将阻止文件被删除,但不会阻止它被复制。最有可能的是,您的程序打开了文件但忘记关闭它。

回答by Klaus Byskov Pedersen

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?

某些重命名工作的事实似乎表明这不是外部锁定问题,而可能是在您的程序中。如果您设置断点,File.Move(oldFilename, newFilename);您仍然可以从资源管理器中重命名它吗?

回答by Christian Hayter

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 Explorerand Process Monitorutilities from Microsoft SysInternals.

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

  1. 源文件确实被另一个应用程序保持打开状态。根据我的经验,许多 Windows 应用程序将文件打开的时间超过了它们应有的时间。在这方面,Windows 资源管理器可能是最糟糕的罪犯。我建议您查看Microsoft SysInternals的Process ExplorerProcess Monitor实用程序。

  2. 目标文件已存在。您应该在您的方法中检查它并检查源文件。

回答by Oded

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 FileMonto check who owns the lock on the file.

您可以使用FileMon来检查谁拥有文件的锁。

回答by James

See File.Moveon MSDN.

请参阅MSDN 上的File.Move

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

具体来说 You cannot use the Move method to overwrite an existing file.

回答by dbkk

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.

文件可能仍在被您系统上的某个进程使用,很可能是您的程序。您可以使用 Process Explorer 来检查哪个进程正在使用该文件,然后从那里走得更远。

回答by user2258428

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

回答by Alan Hadsell

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

将文件重命名为相同名称会出现此错误。

回答by ALEXintlsos

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.

当我误解 File.Move 文档(“将指定文件移动到新位置,提供指定新文件名的选项”)时出现此错误,这意味着如果您只指定目标目录而不是新文件名,它会起作用。当然不是;您不仅必须指定新目录,还必须指定文件名,即使它与源文件名相同。我不知道为什么这个错误会变成“被另一个进程使用”。