Как я могу избавиться от времени ожидания между двумя методами, которые обращаются к одному и тому же файлу? - PullRequest
0 голосов
/ 03 января 2011

У меня есть следующий фрагмент кода 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 - это метод ReadLine, который вызывается, пока AtEndOfStream еще не закончил. Однако использование 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' и обрабатывается позже.

Ответы [ 4 ]

1 голос
/ 25 января 2011

Вот, пожалуйста, этот код будет выполнять цикл.Проблема, с которой вы столкнулись, заключалась в повторном использовании строки чтения для того же потока, и она читала после 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
1 голос
/ 06 января 2011

код, который вы разместили, прекрасно работает для меня. я не получаю исключения ...

Вы обращаетесь к файлу где-нибудь еще, используя ваш опубликованный код?

Вы пытались прочитать весь файл и затем проанализировать строку? см http://www.motobit.com/tips/detpg_asp-vbs-read-write-ini-files/

0 голосов
/ 03 мая 2011

Спасибо всем за ваши ответы. просмотр ваших предложенных кодов и их изучение заставило меня осознать, что с моим собственным кодом в первую очередь все было в порядке (хотя в то время было 2 цикла while, он правильно выходил из них). Попробовав предложенные вами коды, я все же обнаружил, что он случайно утвержден в моих тестовых примерах, и, подумав об этом, я понял, что основное приложение, которое я тестирую, все еще обращалось к этому файлу (хотя я не знаю, для чего, но это что-то еще).

Я нашел решение, которое мы всегда предлагаем при ручном тестировании; скопируйте оригинал и работайте над копией.

Кроме того, спасибо за ваши предложенные коды, они дали мне разные ракурсы, чтобы улучшить дизайн и удобство чтения кода.

0 голосов
/ 07 января 2011

Функция ReadIni (myFilePath, mySection, myKey) 'Эта функция возвращает значение, считанное из файла INI' 'Аргументы:' myFilePath [строка] имя (путь и) файла INI файла 'mySection [строка] разделв файле INI для поиска 'myKey [строка] ключ, значение которого должно быть возвращено' 'Возвращает:' значение [строка] для указанного ключа в указанном разделе '

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

...