这与简单的文件复制操作代码有关。我的要求是只有新文件从源文件夹复制到目标文件夹,所以在复制文件之前,我检查一下:
在此之后,我继续进行复制操作
但是,我随机获得一个IOException,声明“文件< filename>已经存在。”
现在,我在2台服务器上运行此代码(作为win服务的一部分),所以我愿意承认,也许,只是可能,在Server1检查条件并继续复制文件的短暂间隔内,Server2复制它到目标,导致Server1上的IOException
但是,我有几千个文件被复制,我得到了数千个这个错误。这怎么可能?我错过了什么?这是代码:
try
{
if(File.Exists(String.Format("{0}\\{1}",pstrSourcePath,strFileName)) && !File.Exists(String.Format("{0}\\{1}",pstrDestPath,strFileName)))
File.Copy(String.Format("{0}\\{1}",pstrSourcePath,strFileName),String.Format("{0}\\{1}",pstrDestPath,strFileName))
}
catch(IOException ioEx)
{
txtDesc.Value=ioEx.Message;
}
答案 0 :(得分:6)
我想象这是一个权限问题。来自File.Exists
的文档:
如果调用者没有足够的权限来读取指定的文件,则不会抛出任何异常,并且无论路径是否存在,该方法都会返回false。
文件可能存在,但您的代码无权检查它?
请注意,如果您为每个文件使用string.Format
一次并将结果保存到临时变量,则代码会更清晰。最好使用Path.Combine
代替string.Format
,如下所示:
string sourcePath = Path.Combine(pstrSourcePath, strFileName);
string targetPath = Path.Combine(pstrDestPath, strFileName);
if (File.Exists(sourcePath) && !File.Exists(targetPath))
{
File.Copy(sourcePath, targetPath);
}
(我也放弃了str
和pstr
前缀,但是嘿......)
答案 1 :(得分:1)
两个服务器场景足以解释问题。请注意,他们将具有自动同步彼此的复制操作的诀窍。无论服务器背后的是什么,都会很快赶上,因为该文件已存在于目标机器的文件系统缓存中。
你必须放弃File.Exist测试,它无法在多任务操作系统上可靠地工作。竞争条件无法解决,因为Windows和.NET都没有例如IsFileLocked()方法。只需调用File.Copy()即可。如果文件已存在,您当然会得到IOException。使用Marshal.GetLastWin32Error()过滤掉异常消息。 ERROR_FILE_EXISTS错误代码为80。
答案 2 :(得分:0)
同样的事情发生在我身上,我无法弄明白。在我的情况下,我总是写到一个新的位置,但有时我收到相同的错误。当我查看该位置时,有一个文件,其名称大小为零字节。我可以保证该文件之前不存在,而其他一些进程也不会写入该位置。这是复制到网络共享,不知道这是否重要,但我想我会提到它。它几乎就像File.Copy操作正在写文件,然后犯错,因为文件存在(但并非总是如此)。我正在记录我的复制操作,因为我递归目录结构并且看不到可能重叠的重复复制操作。