0

プレーンテキストファイルでセクション(strSection)とそのセクション内のアイテム(strItem)を見つけるための次のVBSCriptコードがあります。

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」に格納されたままになり、後で処理されます。

4

4 に答える 4

1

あなたが投稿したコードは私にとって完璧に機能します。例外はありません...

投稿されたコードを使用しているときに、他の場所でファイルにアクセスしていますか?

ファイル全体を読み取ってから文字列を解析してみましたか?http://www.motobit.com/tips/detpg_asp-vbs-read-write-ini-files/を参照してください

于 2011-01-06T09:07:25.667 に答える
1

さあ、このコードはループを実行します。あなたが抱えていた問題は、同じストリームの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
于 2011-01-24T22:53:01.810 に答える
0

関数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

終了機能

于 2011-01-07T14:00:46.023 に答える
0

返信ありがとうございます。提案されたコードを見て調べてみると、そもそも自分のコードに問題はないことがわかりました(whileループが2つあったとしても、正しく終了しました)。提案されたコードを試した後も、テストケース内でランダムにアサートされていることがわかりました。それについて考えた後、テストしているメインアプリケーションがまだこのファイルにアクセスしていることに気付きました(何のためかはわかりませんが、それは別のことです)。

私が見つけた解決策は、手動テストの際に常に提案する解決策でした。オリジナルをコピーして、コピーに取り組みます。

また、提案されたコードのおかげで、コードのデザインと読みやすさを向上させるためにさまざまな角度が与えられました。

于 2011-05-03T11:14:58.553 に答える