How can I get rid of wait time between 2 methods that access the same file?
我有以下一段VBSCript代码,可以在纯文本文件中找到一个部分(strSection)和该部分中的项目(strItem)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | Do While Not myINIFile.AtEndOfStream sl_Sleep(100) s = myINIFile.ReadLine <--- **This is the line that rises the exception** If s = strSection Then 'Find the correct line Do While Not myINIFile.AtEndOfStream s = myINIFile.ReadLine If InStr(s, strItem)>0 Then Exit Do End if Loop Exit Do End if Loop |
看来,如果我不输入Sleep(100)(毫秒)(或使用较低的值,例如20或50),我最终会得到一个异常,指出"该进程无法访问文件,因为另一个进程已锁定了一部分文件"。
我认为在AtEndOfStream尚未完成时,正在调用Do While中的条件是ReadLine方法。但是,对于每条线使用100毫秒会将进程减慢到无法接受的速度。
这是真正发生的事情还是其他地方的问题?
有什么我可以做的事情,以防止该过程被锁定或等待更多时间(直到它被释放)(只有在锁定后才不会引发异常)?
编辑:此代码循环遍历如下所示的文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | [Section1] param1 = 100 param2 = 200 param3 = 300 [Section2] param1 = 1000 param2 = 2000 param3 = 3000 [Section3] param1 = 1 param2 = 2 param3 = 5 param4 = 10 param5 = 20 |
代码应该遍历文件,直到找到[SectionX]行(strSection),然后继续读取行,直到找到" paramx"行(strItem)。然后将该行保留在" s"中,并在以后进行处理。
在这里,此代码将执行循环。您遇到的问题是对同一流重新使用readline,并且读取了EOF之后(和/或)创建了文件锁争用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | Const TristateFalse = 0 Const ForReading = 1 strINIfile ="c:\\scripts\\testconfig.ini" strSection ="[Section2]" strItem ="param3" Set objFSO = WScript.CreateObject("Scripting.Filesystemobject") Set objINIstream = objFSO.OpenTextFile(strINIfile, ForReading, False, TristateFalse) boolCheckSection = False Do While Not objINIstream.AtEndOfStream strLine = Trim(objINIstream.ReadLine) ' Determine if we're in the section, set boolcheck if so If InStr(UCase(strLine),UCase(strSection)) Then boolCheckSection = True ElseIf InStr(UCase(strLine),"[") Then boolCheckSection = False End If ' If so, read the proper value and store in variable If boolCheckSection Then If InStr(UCase(strLine), UCase(strItem)) Then tmpParam = Split(strLine,"=") strParamValue = Trim(tmpParam(1)) Exit Do ' exit loop with set variable End If End If Loop WScript.Echo strParamValue |
您发布的代码非常适合我。我没有例外...
您在使用发布的代码时是否正在其他任何地方访问文件?
您是否尝试读取整个文件,然后解析字符串?参见http://www.motobit.com/tips/detpg_asp-vbs-read-write-ini-files/
感谢大家的答复。查看您提出的代码并进行研究,使我意识到我自己的代码没有任何错误(即使有2个while循环,它也正确退出了它们)。在尝试了您提出的代码之后,我仍然发现它在我的测试用例中是随机断言的,并且在考虑了它之后,我意识到我正在测试的主应用程序仍然访问了该文件(尽管我不知道它是做什么的,但这是另外一回事)。
我发现的解决方案是我们在手动测试时始终建议的解决方案。复制原件并进行复印。
此外,感谢您提出的代码,它们给了我不同的angular,以改善我的代码设计和可读性。
函数ReadIni(myFilePath,mySection,myKey)
'此函数返回从INI文件读取的值
'
的参数:
'myFilePath [string] INI文件的(路径和)文件名
'mySection [string] INI文件中要搜索的部分
'myKey [string]要返回其值的键
'
返回:
'指定部分中指定键的[string]值
'
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | Const ForReading = 1 Const ForWriting = 2 Const ForAppending = 8 Dim intEqualPos Dim objFSO, objIniFile Dim strFilePath, strKey, strLeftString, strLine, strSection Set objFSO = CreateObject("Scripting.FileSystemObject" ) ReadIni ="" strFilePath = Trim( myFilePath ) strSection = Trim( mySection ) strKey = Trim( myKey ) If objFSO.FileExists( strFilePath ) Then Set objIniFile = objFSO.OpenTextFile( strFilePath, ForReading, False ) Do While objIniFile.AtEndOfStream = False strLine = Trim( objIniFile.ReadLine ) ' Check if section is found in the current line If LCase( strLine ) ="[" & LCase( strSection ) &"]" Then strLine = Trim( objIniFile.ReadLine ) ' Parse lines until the next section is reached Do While Left( strLine, 1 ) <>"[" ' Find position of equal sign in the line intEqualPos = InStr( 1, strLine,"=", 1 ) If intEqualPos > 0 Then strLeftString = Trim( Left( strLine, intEqualPos - 1 ) ) ' Check if item is found in the current line If LCase( strLeftString ) = LCase( strKey ) Then ReadIni = Trim( Mid( strLine, intEqualPos + 1 ) ) ' In case the item exists but value is blank If ReadIni ="" Then ReadIni ="" End If ' Abort loop when item is found Exit Do End If End If ' Abort if the end of the INI file is reached If objIniFile.AtEndOfStream Then Exit Do ' Continue with next line strLine = Trim( objIniFile.ReadLine ) Loop Exit Do End If Loop objIniFile.Close Else WScript.Echo strFilePath &" doesn't exists. Exiting..." Wscript.Quit 1 End If |
结束功能