How can I get rid of wait time between 2 methods that access the same file?
I have the following piece of VBSCript code to find a section (strSection) and an item in that section (strItem) in a plain text file.
开发者_StackOverflowDo 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
It seems that if I do not put the Sleep(100) (milliseconds) (or use lower values like 20 or 50) I eventually get an exception that says "The process cannot access the file because another process has locked a portion of the file".
I think that the condition in the Do While is the ReadLine method is being called while the AtEndOfStream has not yet finished. However, using 100 msecs for every line is slowing down the process to unacceptable speeds.
Is this what is really happening or is the problem somewhere else? Is there anything that I can do to prevent this process from being locked or to wait a little more (until it is freed) only if it is locked so it does not raise an exception?
EDIT: This code loops through a file that looks like this:
[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
The code is supposed to go through the file until it finds the [SectionX] line (strSection) and then keep reading lines until it finds the "paramx" line (strItem). This line is then kept stored in 's' and it is processed later on.
the code you posted works perfectly for me. i don't get an exception...
are you accessing the file anywhere else while using your posted code?
have you tried reading the entire file and then parse the string? see http://www.motobit.com/tips/detpg_asp-vbs-read-write-ini-files/
Here you go, this code will perform the loop. The problem you were having was reusing the readline for the same stream and it was reading past the EOF (and/or) creating a file lock contention.
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
Function ReadIni( myFilePath, mySection, myKey ) ' This function returns a value read from an INI file ' ' Arguments: ' myFilePath [string] the (path and) file name of the INI file ' mySection [string] the section in the INI file to be searched ' myKey [string] the key whose value is to be returned ' ' Returns: ' the [string] value for the specified key in the specified section '
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
End Function
Thanks to all for your replies. looking at your proposed codes and studying them made me realize that there was nothing wrong with my own code in the first place (even though there were 2 while loops, it exited them properly). After trying your proposed codes I still found that it randomly asserted within my test cases and after thinking about it I realized that the main application I am testing still accessed this file (although I do not know what for, but that is something else).
The solution I found was one we always suggest when manual testing; copy the original and work on the copy.
Also, thanks for your proposed codes, they gave me different angles to improve my code design and readability.
精彩评论