【问题标题】:Runtime Error 53 "File Not Found" from LotusScript agent (SOLVED)来自 LotusScript 代理的运行时错误 53“找不到文件”(已解决)
【发布时间】:2021-05-18 10:04:38
【问题描述】:

由于未知原因,服务器端 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 对服务器和相关存档文件具有最大访问权限(策略 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。 然后再次查看设计师帮助我发现了这个小笔记:

FileLen 返回一个 Long 值

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

非常奇怪的错误信息,不过,我想说...

感谢所有帮助我思考的人;)

【问题讨论】:

  • Domino 将数据库锁定在其访问范围内,以便在 Domino 之外进行访问。我永远不会尝试从文件系统中获取此类信息...为什么不使用 NotesDBDirectory?
  • 是的,使用 NotesDBDirectory 是我最初的计划。但后来我意识到这个方法有 2 周的时间点: - #1 循环这个对象我无法控制要循环的文件夹。有问题的服务器拥有数万个数据库,但我只对 \archive 文件夹下的数据库感兴趣,它始终是整个服务器。 - #2 这个对象我只能访问数据库对象。如果它存储在正确的文件夹中,我必须查看它,然后它的文件名是否遵循给定的模式。如果两者都是这种情况,我必须打开数据库才能查看它的大小
  • 和文件名中的特殊字符有关系吗?
  • NotesDBDirectory 是一个相当快的对象。除非您打开数据库,否则循环数千个数据库只需几秒钟(NotesDatabase- 通过 NotesDBDirectory 获得的对象未打开,您需要为您感兴趣的数据库调用 db.Open("", ""))。并且可以从关闭的对象中读取文件路径:If Left( db.FilePath , 8 ) = "archive\" then。这将非常快,因为您只需要真正打开正确路径中的文件...
  • @Duston - 不应该是个问题。该模式基本上是“a_EmpID.nsf”,其中 EmpId 是 6 个字符,以“E”开头,然后是第二个简单的 ASCII 字符(通常是 A 到 E),然后是 4 位数字。但仔细观察仍然是个好主意——也许有一些“看不见”的特殊字符。我会检查的

标签: lotus-notes lotus-domino lotusscript hcl-notes


【解决方案1】:

LotusScript 可能正在调用 32 位 WinAPI 以获取文件长度,此调用将返回一个无符号的 32 位值,最大文件大小约为 4.2Gb。但是,LS 不支持无符号的 32 位值,仅支持有符号,因此任何超过 2.1Gb 的返回值都用负值表示。

您可以取负值的绝对值并将其放入货币或单/浮点数中,并添加 2.1Gb 以获得最大 4.2Gb 的文件大小,但不会更大,因为 API 调用不会返回一个更大的数字,因此,API 调用可能不会认为这是一个错误,并且 LS 在技术上没有“溢出”产生大小错误。

或者,如果您认为任何超过 1Gb 的大小都是“可报告的”,只需查找 +ve 和 > 1gb 或

【讨论】:

  • 确实是非常有趣的想法,而且您的假设很可能是正确的。感谢您分享您的想法! - 我必须解决这个问题已经快一年了。只是查了一下:我终于按照@Tode 在上面的评论中推荐的那样使用 NotesDbDirectory 对象解决了这个问题。在生成的报告中,我仍然看到很多条目返回的 db 大小为“-1”。客户和我最终决定这是足够的信息,因为很明显这些数据库是,而不知道“-1”输出的原因。现在我想我知道了,非常感谢!
【解决方案2】:

由于您只从磁盘读取: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

【讨论】:

  • 感谢您的输入,但我已经知道代码“失败”在哪个文件上:在错误 53 上我恢复然后将文件名写入我的报告
  • 根据您在 DIR 中的过滤器,您的所有文件都是 *.nsf,因此它似乎不相关,但请查看 bytes.com/topic/access/answers/…
  • 确实很有趣,感谢您的链接。我不觉得它是相关的,但我也觉得我的代码应该按原样工作:D 仍然可以从 VB / VBA 脚本中尝试同样的方式
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-12-29
  • 1970-01-01
  • 2018-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-12
相关资源
最近更新 更多