如何在Nunit测试中使用File.Exists函数

4
我有一个方法,它在执行一些文件内容操作之前会测试文件是否存在,如下所示:
Private Sub AddHeaderToLogFile()
    ''#Only if file does not exist
    If Not File.Exists(_logPath) Then
        Dim headerLogger As Logger
        headerLogger = LogManager.GetLogger("HeaderLogger")
        ''#Use GlobalDiagnosticContext in 2.0, GDC in pre-2.0
        NLog.GlobalDiagnosticsContext.Set("appName", _appName)
        NLog.GlobalDiagnosticsContext.Set("fileVersion", _fileVersion)
        NLog.GlobalDiagnosticsContext.Set("logId", 0)
        headerLogger.Info("")
    End If
End Sub

这个方法的思路是,如果文件不存在,则通过调用NLog记录器实例来生成文件,在此时创建文件并插入指定的头部信息。该方法在应用程序本身中运行良好,但我有一个简单的NUnit测试,实现了一个测试方法来验证文件是否按预期创建和填充。当我通过调试器逐步执行时,我发现'_logPath'被设置为:
D:\Documents and Settings\TE602510\Local Settings\Temp\nunit20\ShadowCopyCache\4288_634286300896838506\Tests_-1937845265\assembly\dl3\7cdfe61a\aa18c98d_f0a1cb01\logs\2010-12-22.log
不幸的是,尽管文件确实存在,但File.Exists的调用返回false。从早些时候查看配置路径的情况来看,上述路径似乎对于这些NUnit测试是正确的。有人知道这里发生了什么事情,以及我需要做什么才能得到所需的结果吗?根据XP文件系统的路径名,日志文件的路径名如下:
D:\Documents and Settings\TE602510\My Documents_VSSWorkArea\PsalertsIp\Tests\bin\Debug\logs
顺祝商祺,
Paul J.

对我来说,这听起来像是框架的一个错误。 - Bobby
2个回答

0

不要使用File.Exists!

文件系统是易变的,因此您正在查找的文件的存在(或不存在)可能会在检查和处理结果之间发生更改。此外,File.Exists无法确定您是否具有有关文件的正确权限。

相反,您想要在这里做的就是尝试正确打开文件,像这样:

Try
    Using fs As IO.FileStream = IO.File.Open(_logPath, FileMode.CreateNew)

    End Using
Catch ex AS IOException 
    ''# This will be thrown if the file already exists - just swallow it
    ''# If you also want to handle IOExceptions while working on the file,
    ''#  place another try/catch inside the using block
End Try

只有当文件的存在本身具有意义,但实际上永远不会读取或写入该文件时,才应使用File.Exists。例如,一些主机系统将创建和销毁文件以指示锁定或表示作业完成。


0

这可能是一个权限问题。根据MSDNFile.Exists(path)返回:

true如果调用者具有所需的权限并且path包含现有文件的名称;否则,false。如果path是空引用(Visual Basic中的Nothing)、无效路径或零长度字符串,则此方法还将返回false。如果调用者没有足够的权限读取指定的文件,则不会引发任何异常,并且该方法无论path是否存在都将返回false

编辑 以下是两种尝试获取目录/文件ACL的方法。可能是因为NUnit被调用的方式导致权限不同。

Private Shared Function DoesFileExist(ByVal file As String) As Boolean
    Try
        Dim FI As New System.IO.FileInfo(file)
        Dim AC = FI.GetAccessControl()              'This method will fail if the file is not found'
        Return True
    Catch ex As System.IO.FileNotFoundException     'FNF error should be thrown if it does not exist'
        Return False
    Catch ex As Exception
        'If you do not have permission to read the permissions this might throw, too.'
        'Of course, in that situation that means that the file exists so we should'
        'probably return True here, too. For debugging I am still throwing though.'
        Throw ex
    End Try
End Function
Private Shared Function DoesDirectoryExist(ByVal dir As String) As Boolean
    Try
        Dim DI As New System.IO.DirectoryInfo(dir)
        Dim AC = DI.GetAccessControl()               'This method will fail if the directory is not found'
        Return True
    Catch ex As System.IO.DirectoryNotFoundException 'DNF error should be thrown if it does not exist'
        Return False
    Catch ex As Exception
        'If you do not have permission to read the permissions this might throw, too.'
        'Of course, in that situation that means that the directory exists so we should'
        'probably return True here, too. For debugging I am still throwing though.'
        Throw ex
    End Try
End Function

Chris,感谢您的回复。很难看出权限如何成为问题,所描述的路径位于“我的文档”文件夹结构内,涉及的文件在运行时创建没有任何问题。我猜测这可能与NUnit生成路径的方式有关(即不是实际物理路径名)... - Paul Johnson
请记住,文件系统是易失性的 - 这些方法应该使用过去式来命名。 - Joel Coehoorn
1
几毫秒前文件是否存在? - Chris Haas
如果错误确实来自日志位置,您可以关闭NUnit影像复制选项(并直接从调试文件夹运行测试)。 - Benoittr

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