如何消除访问同一文件的两种方法之间的等待时间?

发布于 2024-10-10 02:54:13 字数 1166 浏览 3 评论 0原文

我有以下一段 VBSCript 代码,用于在纯文本文件中查找一个部分 (strSection) 以及该部分中的一个项目 (strItem)。

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),我最终会得到一个异常,显示“该进程无法访问该文件,因为另一个进程已锁定该文件的一部分” ”。

我认为 Do While 中的条件是在 AtEndOfStream 尚未完成时正在调用 ReadLine 方法。然而,每行使用 100 毫秒会使处理速度减慢至无法接受的速度。

这是真正发生的事情还是其他地方有问题? 我可以采取什么措施来防止此进程被锁定,或者在它被锁定时再等待一段时间(直到它被释放),这样它就不会引发异常?


编辑:此代码循环遍历一个如下所示的文件:

[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' 中并稍后进行处理。

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.

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 

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

听闻余生 2024-10-17 02:54:13

您发布的代码非常适合我。我没有遇到异常...

您在使用发布的代码时是否在其他地方访问该文件?

您是否尝试过读取整个文件然后解析字符串?请参阅http://www.motobit.com/tips/detpg_asp -vbs-读-写-ini-文件/

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/

留一抹残留的笑 2024-10-17 02:54:13

在这里,这段代码将执行循环。您遇到的问题是为同一流重用 readline,并且它读取超过 EOF(和/或)创建文件锁争用。

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

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
黑寡妇 2024-10-17 02:54:13

函数 ReadIni( myFilePath, mySection, myKey )
' 该函数返回从 INI 文件读取的值
'
' 论据:
' myFilePath [string] INI 文件的(路径和)文件名
' mySection [string] INI 文件中要搜索的部分
' myKey [string] 要返回值的键
'
' 返回:
' 指定部分中指定键的 [string] 值
'

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

结束函数

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

一刻暧昧 2024-10-17 02:54:13

感谢大家的回复。查看您提出的代码并研究它们让我意识到我自己的代码首先没有任何问题(即使有 2 个 while 循环,它也正确退出了它们)。在尝试了您提出的代码之后,我仍然发现它在我的测试用例中随机断言,并且经过思考,我意识到我正在测试的主应用程序仍然访问了这个文件(虽然我不知道为什么,但那是别的东西)。

我找到的解决方案是我们在手动测试时总是建议的解决方案;复制原件并在副本上进行处理。

另外,感谢您提出的代码,他们给了我不同的角度来改进我的代码设计和可读性。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文