File.Copy FileNotFoundException随机报告,因为它永远不会成立

时间:2009-11-19 15:19:46

标签: vb.net

代码非常简单。

If File.Exists(strFileMovingTo) Then File.Delete(strFileMovingTo)
If File.Exists(strFileMovingTo) Then
    Call SendEmail(Globals.EmailInternetTeam, "dev-sql@fad.co.uk", "Display Jpg Problem", "The file " & strFileMovingTo & " cannot be removed by the file mover(to allow a new file to be moved over)")
    Return False
Else
    If File.Exists(strFileMovingFrom) Then
        File.Copy(strFileMovingFrom, strFileMovingTo, True)
        If File.Exists(strFileMovingTo) = False Then
            ''tried to copy file over but must have failed ... send email
            Call SendEmail(Globals.EmailInternetTeam, "dev-sql@friday-ad.co.uk", "Display Jpg Problem", "The file cannot be moved by the file mover from " & strFileMovingFrom & " to " & strFileMovingTo & ". Please have a look at why.")
            Return False
        Else
            Return True
        End If
    End If
    Return False
    ''make sure this file exists on fad dev
End If

然而,FileNotFoundException期间会抛出File.Copy个异常,即使它被If File.Exists ... End If包裹起来以检查它是否存在。

最棒的是,如果你通过调试器运行它几乎总是有效,当作为应用程序发布它几乎永远不会工作。

Scally文件始终存在。

任何人都知道发生了什么事?

5 个答案:

答案 0 :(得分:1)

可能还有其他内容正在删除文件,并且在调用File.Exists和File.Copy之间存在竞争条件。

答案 1 :(得分:0)

它在调试中工作的事实告诉我这是一个时间问题。您没有等待足够长的时间来删除或其他文件系统更改。

在进行文件系统更改后等待一到两秒钟。

<强>更新

如何:创建要执行的文件移动的共享字典,并使用FileSystemWatcher执行复制操作。

If File.Exists(strFileMovingTo) Then File.Delete(strFileMovingTo)
        Thread.Sleep(1000) --Add wait
        If File.Exists(strFileMovingTo) Then
            Call SendEmail(Globals.EmailInternetTeam, "dev-sql@fad.co.uk", "Display Jpg Problem", "The file " & strFileMovingTo & " cannot be removed by the file mover(to allow a new file to be moved over)")
            Return False
        Else
            If File.Exists(strFileMovingFrom) Then
                File.Copy(strFileMovingFrom, strFileMovingTo, True)
                Thread.Sleep(1000) --Add wait
                If File.Exists(strFileMovingTo) = False Then
                    'tried to copy file over but must have failed ... send email
                    Call SendEmail(Globals.EmailInternetTeam, "dev-sql@friday-ad.co.uk", "Display Jpg Problem", "The file cannot be moved by the file mover from " & strFileMovingFrom & " to " & strFileMovingTo & ". Please have a look at why.")
                    Return False
                Else
                    Return True
                End If
            End If
            Return False
            'make sure this file exists on fad dev
        End If

答案 2 :(得分:0)

我同意Dave's answer这看起来像是一个时间问题。此外,如果由于任何原因无法删除文件,则通常File.Delete将抛出异常。也许你应该抓住它并改造你的逻辑。

答案 3 :(得分:0)

有很多竞争条件,你不应该盲目依赖File.Exists进行其他文件操作。任何人都可以在两个函数调用之间删除或添加具有相同名称的文件。

If File.Exists(strFileMovingFrom) Then
    // AT THIS TIME, another thread or another process might run
    // the equivalent to **File.Delete(strFileMovingFrom)**
    File.Copy(strFileMovingFrom, strFileMovingTo, True) //Can throw!

答案 4 :(得分:0)

当使用Windows API的某些文件函数时,对于.NET也应如此,应始终了解文件系统函数的异步性质。异步,意味着在调用API影响文件系统和下次成功调用与文件或目录相关的相同API之间存在非零,不可预测,无保证的时间。

在非事务性API中,通常会调用“create file”之类的东西,然后立即尝试“findFirst”并失败。只需将文件系统视为具有不可预测延迟的消息传递系统,并通过重复轮询,睡眠和超时​​或事件通知和回调来开发一种“协议”。

然而,自从引入Vista以来,当应用程序可以使用如此命名的“事务”文件API时,会有一组不同的保证和期望。