System.IO.File.Move 报错 "文件已存在"

8
通常情况下,如果您尝试移动一个已存在的文件,File.Move会抛出一条消息:“Cannot create a file when that file already exists”(无法创建已存在的文件)。但我遇到了这样一种情况,File.Move抛出了一个异常信息:
"The file exists"(文件已存在)
此异常是由System.IO.__Error.WinIOError直接在File.Move之后抛出的。它试图将一个文件移动到网络驱动器上。经过一番搜索,似乎唯一会引起这个特定消息的东西是Path.GetTempFileName()——如果临时文件夹已满,它就会抛出这个异常。
但我没有使用GetTempFileName,并且临时文件夹也不是满的。有人知道可能是什么原因导致这种情况吗?或者如何进行故障排除?(这是在托管服务器上进行的,只有管理公司可以访问,我无法在此处展示专有代码)。

如果您不提供完整的异常和堆栈跟踪,很难确定问题所在。 - Jim Mischel
1
我会尝试澄清我的问题。这不是一个“找出代码错误”的问题,而是在什么情况下File.Move通常会抛出“文件已存在”的异常? - Leon van der Walt
4个回答

4
这来自于Windows,不同的情况会有不同的错误代码。第二个错误码是ERROR_ALREADY_EXISTS,“当文件已存在时无法创建文件”,当文件从一个目录移动到同一驱动器上的另一个目录时发生。这是一个非常简单的操作,只需要移动目录项即可。
第一个错误码是ERROR_FILE_EXISTS,“文件已存在”,当文件从一个驱动器移动到另一个驱动器时发生。这是一个更为复杂的操作,文件数据也必须被复制。换句话说,它退回到了File.Copy(string,string,bool)的等效操作,其中最后一个参数“overwrite”设置为false。尽管它没有使用相同的错误代码有点奇怪,但对于文件系统驱动程序来说却是一件大事,只是对于您的程序而言不重要。否则,您只会收到一个相当通用的IOException,而不是一个更具体的异常,将文件操作错误细分为更细粒度的异常。
这实际上并不是一个问题,因为在您的代码中并没有任何可以解决这个问题的东西,您需要人类的帮助来纠正这个问题。除非你在自己的代码中采取特定的预防措施,要么避免如果目标文件已经存在则移动,要么先删除目标文件。请注意,无论哪种方法都不是100%可靠的解决方法,有很小的机会,另一个进程在您删除它但在移动之前再次创建文件。在多任务操作系统上使文件操作完全可靠相当困难。

谢谢Hans,你的回答听起来很接近。这是一个移动到网络驱动器的操作(编辑后的问题)。我搜索了相关文档,但没有找到。你有参考资料吗? - Leon van der Walt
一个引用是用来干什么的?据我所知,我刚刚创建了一个。 - Hans Passant
1
我刚刚通过创建一个控制台应用程序,并试图将已存在的文件移动到网络驱动器来确认这一点。 - Leon van der Walt

2

我相信您需要指定文件名,当然前提是您没有这样做。展示代码有助于理解您的问题,但我假设您正在进行以下操作:

File.Move(@"C:\Folder\File.txt", @"C:\Folder2")

相反,尝试:

File.Move(@"C:\Folder\File.txt", @"C:\Folder2\File.txt")

1
你需要转义斜杠或使用逐字字符串。也就是说,要么使用"C:\\Folder\\File.txt",要么使用@"C:\Folder\File.txt" - Jim Mischel
此外,仅提供目录名称会引发与指定存在的文件名相同的异常。 - Jim Mischel
对,我有点心不在焉地放了那个。但我不确定这一点,因为他说他得到了两个不同的错误,一个是当他把它放在文件存在的位置时,但我不知道他是怎么做到的。坦白地说,这很大程度上是猜测,因为我不知道他的代码在哪里出错了。 - noneabove

2

使用 .NET Core 3.0 或更高版本,Move 方法新增了一个布尔参数,将其设置为 true 可以覆盖现有文件。

Move(String, String, Boolean)

关于此事,您可以在这里找到更多信息。


1
还有另一种方法可以实现这个目标:

public void Move(string uncPath)
        {
            var files = Directory.EnumerateFiles(Constants.ROOT_PATH, "*.csv");

            foreach (var file in files)
            {
                var item = file.GetAfter("\\");
                File.Copy(file, uncPath + item);
                File.Delete(file);
            }
        }

我已经测试过了,它运行得非常好。希望对某人有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接