在循环中,我使用FileAppend将文本添加到文件中。在循环的每次迭代中,数据都在一个变量中累积,FileAppend在循环的每n次迭代中被调用以保存数据。偶尔,在FileAppend调用之后,在下一次迭代期间在变量中累积的数据将丢失。由于它是非常间歇性的,我无法重现这种行为。在某些情况下,似乎在FileAppend之后脚本需要延迟。这是一个已知的问题?我已经搜索了AHK论坛和这个网站而没有报道此类问题。
以下是发生这种情况的代码:
Loop, %intMax% ; for each record in the collection
{
if !Mod(A_Index, intProgressIterations)
; update the progress bar and save the data every intProgressIterations
; (when intProgressIterations / A_Index = 0)
{
ProgressUpdate(A_index, intMax, strProgressText)
; update progress bar only every %intProgressIterations% iterations
FileAppend, %strData%, %strFilePath%
strData := ""
; save the data accumulated in strData and empty it
}
strData := strData . BuildData(objCollection[A_Index])
; build the data for this record and add it to strData
}
更确切地说,它是丢失的行strData := strData . BuildData(objCollection[A_Index])
的一次(或多次)迭代的内容。
答案 0 :(得分:1)
可以是任何数量的东西。该文件可能被锁定,您的BuildData函数中可能存在错误,导致它无法生成数据。
我建议您在追加数据之前和之后检查上次修改日期。
如果相同,您可以再试一次和/或通知用户。
关于延迟的问题,它不应该需要它,脚本在完成写入文件之前不会继续下一行代码。
答案 1 :(得分:0)
关于文件锁定的结果,这个带错误管理的代码将更安全:
Loop, %intMax% ; for each record in the collection
{
if !Mod(A_Index, intProgressIterations)
; update the progress bar and save the data every intProgressIterations
; (when intProgressIterations / A_Index = 0)
{
ProgressUpdate(A_index, intMax, strProgressText)
; update progress bar only every %intProgressIterations% iterations
Loop
{
FileAppend, %strData%, %strFilePath%
; save the data accumulated in strData and empty it after the loop
if ErrorLevel
Sleep, 20
}
until !ErrorLevel or (A_Index > 50) ; after 1 second (20ms x 50), we have a problem
if (ErrorLevel)
strError := strError . "Error writing line " . A_Index . " Error: #" . A_LastError . "`n"
strData := ""
}
strData := strData . BuildData(objCollection[A_Index])
; build the data for this record and add it to strData
}
答案 2 :(得分:0)
作为这个问题的补充点(对于将来的搜索)...我发现当输出文件在Dropbox上时,在循环内尝试FileAppend也会导致数据丢失。
Dropbox将在循环的早期循环期间检测文件的更新,然后在将更新的(更新)文件发送到Dropbox服务器时将其锁定。我在文本文件中跟踪的数据丢失短至150行文本。
我使用的解决方案是在Dropbox监控的主文件夹之外创建一个临时输出文件,然后写入它。循环完成后,将临时文件复制回Dropbox,然后删除临时文件。
这是一个部分代码示例,说明在循环结束后我如何使用已完成的临时文件进行切换:
; Copy the Daily Scrub temp file to var holding the filepath to todo.txt, then delete the Daily Scrub temp file
FileCopy, C:\temp-dailyscrub.txt, %todoFilePathParse%, 1
FileDelete, C:\temp-dailyscrub.txt