首页 > 解决方案 > 来自 LotusScript 代理的运行时错误 53“找不到文件”(已解决)

问题描述

由于未知原因,服务器端 LotusScript 代理在尝试读取现有邮件归档文件的物理文件大小时抛出错误 53“找不到文件”。情况如下:

LS 代理正在循环服务器“\Data”目录正下方的给定目录“\archive”中的所有文件。有问题的服务器是在 Windows 2016 服务器上运行的 Domino 10.0.1。LS 代码循环目录查找名称遵循给定模式的数据库文件,例如“ a_EmployeeID.nsf ”。如果数据库的文件名符合模式,则代码使用文件名中的EmployeeID扫描服务器的 names.nsf 以查找存档所有者。如果没有找到该 ID 的人员文档,则代码尝试使用读取数据库的物理文件大小FileLen(filePath & FileName). 然后将生成的数据(文件路径 + 文件大小)+ EmployeeID 写入磁盘上的报告文件。不遵循该模式的文件也至少会写回报告中。该代理背后的想法是找到“孤立”或放错位置的数据库。

对于大约 80% 的扫描文件,这工作正常,具有精确文件大小的记录将写入报告。但对于另外约 20% 的运行时间error 53 "File not found"拉起。在这种情况下,记录只包含文件路径/名称 + EmployeeID(如果可用)+“-1”作为文件大小。因为该文件显然确实存在,所以我认为这是一个访问或安全问题。

代理使用对服务器和相关存档文件具有最大访问权限的管理员 ID 进行签名(策略 ID 在 dbs 的 ACL 中具有管理员访问权限)。代理的安全设置设置为 3 级(具有完全管理员权限的无限制访问),因为我首先使用在服务器上具有完全管理员访问权限的 ID 对代理进行了签名(与现在使用的 ID 相同的结果)。

比较数据库的 ACL,我找不到“有效”和无效的 ACL 之间的任何区别。不过,我看到的是,抛出此错误的显然总是相同的数据库,因此这不是随机问题。

为了完整起见,这里是代理代码的关键部分:

sFileName = Dir$(sPath & "*.nsf")
Do Until sFileName = ""
    iCount = iCount + 1
    sEmpid = "" 'reset
    lSizeArc = 0 'reset
    dblSizeArc = 0 'reset
    sSizeArcFmt = "" 'reset
    If(sFileName Like sPattern) Then
        sEmpid = Left(Right(sFileName, Len(sFileName) - 2), 6)
        Set vec = vwEgid.Getallentriesbykey(sEmpid, True)
        If(vec.count = 0) Then
            On Error 53 Resume Next 'Error 53 ("File not found")
            lSizeArc = FileLen(sPath & sFilename)
            If(Err = 53) Then
                lSizeArc = -1
                sSizeArcFmt = "-1 (no size available)"
                Err = 0
            Else
                dblSizeArc = Round((lSizeArc / 1024 / 1024), 3)
                sSizeArcFmt = Format$(dblSizeArc, "0.000") & " MB"
            End If
            Print #iFileNum,_
                "ORPHANED_ARCHIVE;" & sEmpid & ";" & sFileName & ";" & sSizeArcFmt
        End If
    Else
        On Error 53 Resume Next 'Error 53 ("File not found") 
        lSizeArc = FileLen(sPath & sFilename)
        If(Err = 53) Then
            lSizeArc = -1
            sSizeArcFmt = "-1 (no size available)"
            Err = 0
        Else
            dblSizeArc = Round((lSizeArc / 1024 / 1024), 3)
            sSizeArcFmt = Format$(dblSizeArc, "0.000") & " MB"
        End If
        Print #iFileNum,_
            "BAD_FILE_PATTERN;NO_EGID;" & sFilename & ";" & sSizeArcFmt
    End If
    sFileName = Dir$() 'next file
Loop 

在我开始转向不同的方向之前,比如研究使用 Windows shell 或 .dll 命令之前,我真的很想了解为什么在某些情况下代码坚持认为无法“找到”所查看的某些文件。

有任何想法吗?

更新 2021-05-19

所以最后我找到了解决这个奇怪问题的方法(我承认,这不是对我的编程技能的赞美):再次查看抛出错误 53 的文件,我意识到它们都相当大,确切地说 > 2.1 GB。所以我不得不承认我犯了一个愚蠢的编程错误:给一个 LONG 变量分配一个这样大小的值当然是行不通的。愚蠢的业余错误......(但是为什么代码不会像通常那样抛出正确的错误来告诉值超出限制?)无论如何,所以我将变量更改为DOUBLE。但是:结果还是一样,虽然 >> 错误 53。然后再次查看 Designer 帮助我发现了这个小注释:

FileLen 返回一个 Long 值

换句话说:FileLen 本身无法处理这么大的文件,并且在解释器发现我的错误编码之前显然会引发该错误。换句话说:没有办法那样解决我的问题。回到@TorstenLink 的评论:我现在就用他的方法

非常奇怪的错误信息,我还是会说......

感谢大家帮助我思考 ;)

标签: lotus-noteslotus-dominolotusscripthcl-notes

解决方案


由于您只从磁盘读取:DIR 和 FileLen,因此您不应该遭受文件上的 Domino LOCK(但不要尝试写入!)

我建议您更改代码以确定它落在哪里以及在哪些文件上:

f(vec.count = 0) Then
        placeInCode = 1 'declare this before as int
        On Error 53 Resume goto handelError'Error 53 ("File not found")

在第二部分,影响 placeInCode = 2

然后声明一个

handelError:
    print "we got error 53 on " & sPath & sFilename & " for the " & placeInCode & " part"
    resume next

推荐阅读