我正在使用以下代码检查文件是否存在:
If Len(Dir$(strFile)) > 0 Then
直到今天,这一切都很好。
在某些情况下,我收到以下错误:
错误指向上面的代码行。
我知道该文件不存在,但我不希望出现此错误。
我忘了提一点:文件名是动态的,取决于另一个进程。
我刚刚注意到,当错误发生时,另一个进程返回垃圾,导致大约 2000 个字符的长文件名。
我从来没有意识到文件名的长度是有限制的。
我创建了一个小项目来测试它,结果上限是 259 个字符:
Option Explicit
Private Sub Command1_Click()
Dim strFile As String
Dim intLength As Integer
strFile = App.Path & "\"
intLength = 259 - Len(strFile)
strFile = strFile & String(intLength, "a")
If Len(Dir$(strFile)) = 0 Then
MsgBox "file does not exist"
End If
End Sub
使用 259 的值可以正常工作,但 260 会给出错误。
我使用调用 Windows API 的函数来执行此操作。此函数处理空格和长文件名。
添加到声明部分:
Private Declare Function CloseHandle Lib "Kernel32" (ByVal hObject As Long) As Long
Private Declare Function CreateFile Lib "Kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, lpSecurityAttributes As SECURITY_ATTRIBUTES, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Any) As Long
Private Type SECURITY_ATTRIBUTES
nLength As Long
lpSecurityDescriptor As Long
bInheritHandle As Long
End Type
Private Const OPEN_EXISTING = 3
Private Const FILE_SHARE_READ = &H1
Private Const GENERIC_READ = &H80000000
Private Const INVALID_HANDLE_VALUE = -1
实际功能
Function FileExists(ByVal fSpec As String) As Boolean
Dim lngResult As Long
Dim udtSA As SECURITY_ATTRIBUTES
On Error GoTo errFileExists
If Len(fSpec) > 0 Then
udtSA.nLength = Len(udtSA)
udtSA.bInheritHandle = 1&
udtSA.lpSecurityDescriptor = 0&
lngResult = CreateFile(fSpec, GENERIC_READ, FILE_SHARE_READ, udtSA, OPEN_EXISTING, 0&, 0&)
If lngResult <> INVALID_HANDLE_VALUE Then
Call CloseHandle(lngResult)
FileExists = True
Else
Select Case Err.LastDllError 'some errors may indicate the file exists, but there was an error opening it
Case Is = ERROR_SHARING_VIOLATION
FileExists = True
Case Else
FileExists = False
End Select
End If
End If
Exit Function
errFileExists:
Err.Raise Err.Number, Err.Source, Err.Description, Err.HelpFile, Err.HelpContext
End Function