- Offizieller Beitrag
Das Thema wurde in diesem Post behandelt.
Ich habe die dort gepostete Version meiner UDF jetzt noch etwas verfeinert.
AutoIt
;-- TIME_STAMP 2019-11-21 12:56:14 v 0.3
Opt('MustDeclareVars', 1)
#cs
Struktur Config-Datei (*.cfg)
== Sektion mit Inhalt ==
SECTION;Key=Value;Key=;Key=Value;Key=Value...
Schlüssel ohne Wert MÜSSEN mit einem "=" abgeschlossen werden!
== leere Sektion ==
SECTION
Kommentarzeilen beginnen mit "#"
== Funktionen ==
_CfgRead()
Reads a value from a key in a section
_CfgWrite()
Writes a value for a key in a section
_CfgKeyDelete()
Deletes a key in a section
_CfgSectionDelete()
Deletes a section
_CfgKeyList()
Returns all keys in a section (as array or delimited string)
_CfgSectionList()
Returns all sections (as array or delimited string)
_CfgSectionGetArray()
Returns an 2D array with all key-value-pairs of a section
_CfgSectionWriteArray()
Replaces (or adds) a section from a 2D array with all key-value-pairs
== Hilfsfunktionen ==
__CfgKeyWrite
__CfgSectionRead
__CfgSectionWrite
__CfgSectionDelete
__FileWriteToLine (modified version of _FileWriteToLine)
#ce
; #FUNCTION# ====================================================================================================================
; Name ..........: _CfgRead
; Description ...: Reads the value from a key in a section.
; Syntax ........: _CfgRead($_sCfg, $_sSection, $_sKey[, $_sDefault = ''])
; Parameters ....: $_sCfg - Path of the config file
; $_sSection - Section with the searched key
; $_sKey - The searched key
; $_sDefault - [optional] The default return value. Default is ''.
; Return values .: Success The value of the passed key or if not set, the default value
; Failure The default value, set @error 1 - config file does'nt exist
; The default value, set @error 2 - config file is empty
; The default value, set @error 3 - section does'nt exist
; The default value, set @error 4 - none key-value-pairs in this section
; The default value, set @error 5 - key does'nt exist in this section
; Author ........: BugFix
; ===============================================================================================================================
Func _CfgRead($_sCfg, $_sSection, $_sKey, $_sDefault='')
Local $aSec = __CfgSectionRead($_sCfg, $_sSection)
If $aSec[0] = 0 Then Return SetError(@error,0,0)
Local $aSectionLine = StringSplit($aSec[1], ';', 2) ; $STR_NOCOUNT (2)
If @error Then Return SetError(4,0,0) ; none key-value-pairs in this line
Local $aKeyVal, $sSectionContent = $_sSection
For $i = 1 To UBound($aSectionLine) -1
$aKeyVal = StringSplit($aSectionLine[$i], '=', 2) ; $STR_NOCOUNT (2)
If $aKeyVal[0] = $_sKey Then
If UBound($aKeyVal) = 2 Then
Return $aKeyVal[1]
Else
Return $_sDefault
EndIf
EndIf
Next
Return SetError(5,0,$_sDefault)
EndFunc ;==>_CfgRead
; #FUNCTION# ====================================================================================================================
; Name ..........: _CfgWrite
; Description ...: Writes the value of a key in a section.
; Syntax ........: _CfgWrite($_sCfg, $_sSection, $_sKey, $_sValue)
; Parameters ....: $_sCfg - Path of the config file
; $_sSection - The section
; $_sKey - The key
; $_sValue - The value to store
; Return values .: Success 1
; Author ........: BugFix
; ===============================================================================================================================
Func _CfgWrite($_sCfg, $_sSection, $_sKey, $_sValue)
Local $fH, $aSec = __CfgSectionRead($_sCfg, $_sSection)
Switch @error
Case 1 ; file does'nt exist
Return FileWrite($_sCfg, StringFormat('%s;%s=%s\n', $_sSection, $_sKey, $_sValue))
Case 2 ; file is empty
$fH = FileOpen($_sCfg, 2) ; $FO_OVERWRITE (2)
FileWrite($fH, StringFormat('%s;%s=%s\n', $_sSection, $_sKey, $_sValue))
Return FileClose($fH)
Case 3 ; section does'nt exist
Return __CfgSectionWrite($_sCfg, StringFormat('%s;%s=%s\n', $_sSection, $_sKey, $_sValue), $aSec[0])
EndSwitch
; otherwise: section exists
Local $sSectionContent = __CfgKeyWrite($_sSection, $aSec[1], $_sKey, $_sValue)
Return __CfgSectionWrite($_sCfg, $sSectionContent, $aSec[0])
EndFunc ;==>_CfgWrite
; #FUNCTION# ====================================================================================================================
; Name ..........: _CfgKeyDelete
; Description ...: Deletes a key-value-pair in a section
; Syntax ........: _CfgKeyDelete($_sCfg, $_sSection, $_sKey)
; Parameters ....: $_sCfg - Path of the config file
; $_sSection - Section with the searched key
; $_sKey - The key to delete
; Return values .: Success 1
; Failure 0, set @error 1 - config file does'nt exist
; 0, set @error 2 - config file is empty
; 0, set @error 3 - section does'nt exist
; 0, set @error 4 - none key-value-pairs in this section
; 0, set @error 5 - key does'nt exist
; Author ........: BugFix
; ===============================================================================================================================
Func _CfgKeyDelete($_sCfg, $_sSection, $_sKey)
Local $aSec = __CfgSectionRead($_sCfg, $_sSection)
If $aSec[0] = 0 Then Return SetError(@error,0,0)
Local $aSectionLine = StringSplit($aSec[1], ';', 2) ; $STR_NOCOUNT (2)
If @error Then Return SetError(4,0,0) ; none key-value-pairs in this line
Local $aKeyVal, $sSectionContent = $_sSection, $bDeleted = False
For $i = 1 To UBound($aSectionLine) -1
$aKeyVal = StringSplit($aSectionLine[$i], '=', 2) ; $STR_NOCOUNT (2)
If $aKeyVal[0] = $_sKey Then
; do nothing, will not write again
$bDeleted = True
Else
$sSectionContent &= StringFormat(';%s=%s', $aKeyVal[0], $aKeyVal[1])
EndIf
Next
If Not $bDeleted Then Return SetError(5,0,0)
Return __CfgSectionWrite($_sCfg, $sSectionContent, $aSec[0])
EndFunc ;==>_CfgKeyDelete
; #FUNCTION# ====================================================================================================================
; Name ..........: _CfgSectionDelete
; Description ...: Deletes a section
; Syntax ........: _CfgSectionDelete($_sCfg, $_sSection)
; Parameters ....: $_sCfg - Path of the config file
; $_sSection - The Section to delete
; Return values .: Success 1
; Failure 0, set @error 1 - config file does'nt exist
; 0, set @error 2 - config file is empty
; 0, set @error 3 - section does'nt exist
; Author ........: BugFix
; ===============================================================================================================================
Func _CfgSectionDelete($_sCfg, $_sSection)
Local $aSec = __CfgSectionRead($_sCfg, $_sSection)
If $aSec[0] = 0 Then Return SetError(@error,0,0)
Return __CfgSectionDelete($_sCfg, $aSec[0])
EndFunc ;==>_CfgSectionDelete
; #FUNCTION# ====================================================================================================================
; Name ..........: _CfgSectionList
; Description ...: Returns a array or string of all section names
; Syntax ........: _CfgSectionList($_sCfg[, $_bRetArray=True])
; Parameters ....: $_sCfg - Path of the config file
; $_bRetArray - [optional] Return as array or delimited string, Default is True - Array
; Return values .: Success Array with all section names, count of sections on index [0]
; Failure 0, set @error 1 - config file does'nt exist
; 0, set @error 2 - config file is empty
; Author ........: BugFix
; ===============================================================================================================================
Func _CfgSectionList($_sCfg, $_bRetArray=True)
If Not FileExists($_sCfg) Then Return SetError(1,0,0)
Local $aSectionLine, $aKeyVal, $sRet = ''
Local $aCfg = FileReadToArray($_sCfg)
If @error = 2 Then Return SetError(2,0,0) ; empty file
For $i = 0 To UBound($aCfg) -1
If StringLeft($aCfg[$i], 1) = '#' Then ContinueLoop ; its a comment line - skip
$aSectionLine = StringSplit($aCfg[$i], ';', 2) ; $STR_NOCOUNT (2)
$sRet &= $aSectionLine[0] & ';'
Next
$sRet = StringTrimRight($sRet, 1)
Return ($_bRetArray ? StringSplit($sRet, ';') : $sRet)
EndFunc ;==>_CfgSectionList
; #FUNCTION# ====================================================================================================================
; Name ..........: _CfgKeyList
; Description ...: Returns a array or string of all key names in a section
; Syntax ........: _CfgKeyList($_sCfg, $_sSection[, $_bRetArray=True])
; Parameters ....: $_sCfg - Path of the config file
; $_sSection - Section to get the keys from
; $_bRetArray - [optional] Return as array or delimited string, Default is True - Array
; Return values .: Success 1
; Failure 0, set @error 1 - config file does'nt exist
; 0, set @error 2 - config file is empty
; 0, set @error 3 - section does'nt exist
; 0, set @error 4 - none key-value-pairs in this section
; Author ........: BugFix
; ===============================================================================================================================
Func _CfgKeyList($_sCfg, $_sSection, $_bRetArray=True)
Local $sRet = '', $aRet[1]
Local $aSec = __CfgSectionRead($_sCfg, $_sSection)
If $aSec[0] = 0 Then Return SetError(@error,0,($_bRetArray ? $aRet : $sRet))
Local $aKeys = StringRegExp($aSec[1], "([^=;]+)=", 3)
If Not IsArray($aKeys) Then Return SetError(4,0,($_bRetArray ? $aRet : $sRet))
If $_bRetArray Then Return $aKeys
For $i = 0 To UBound($aKeys) -1
$sRet &= $aKeys[$i] & ';'
Next
Return StringTrimRight($sRet, 1)
EndFunc ;==>_CfgKeyList
; #FUNCTION# ====================================================================================================================
; Name ..........: _CfgSectionGetArray
; Description ...: Returns a 2D array of all key-value-pairs in a section
; Syntax ........: _CfgSectionGetArray($_sCfg, $_sSection)
; Parameters ....: $_sCfg - Path of the config file
; $_sSection - Section to get the key-value-pairs from
; Return values .: Success 2D array: [[count_keys,section_name],[key_1,value],[key_2,value], .. [key_n,value]]
; Failure [[0,"error"]], set @error 1 - config file does'nt exist
; [[0,"error"]], set @error 2 - config file is empty
; [[0,"error"]], set @error 3 - section does'nt exist
; Author ........: BugFix
; ===============================================================================================================================
Func _CfgSectionGetArray($_sCfg, $_sSection)
Local $aRet[1][2] = [[0,"error"]]
Local $aSec = __CfgSectionRead($_sCfg, $_sSection)
If $aSec[0] = 0 Then Return SetError(@error,0,$aRet)
Local $aSectionLine = StringSplit($aSec[1], ';', 2) ; $STR_NOCOUNT (2)
If @error Then ; none key-value-pairs in this line
$aRet[0][1] = $_sSection
Return $aRet
EndIf
Local $aKeyVal, $iCnt = UBound($aSectionLine)
ReDim $aRet[$iCnt][2]
$aRet[0][0] = $iCnt -1
$aRet[0][1] = $_sSection
For $i = 1 To UBound($aSectionLine) -1
$aKeyVal = StringSplit($aSectionLine[$i], '=', 2) ; $STR_NOCOUNT (2)
$aRet[$i][0] = $aKeyVal[0]
$aRet[$i][1] = (UBound($aKeyVal) = 2 ? $aKeyVal[1] : '')
Next
EndFunc ;==>_CfgSectionGetArray
; #FUNCTION# ====================================================================================================================
; Name ..........: _CfgSectionWriteArray
; Description ...: Writes the whole section at once from a passed 2D array with all key-value-pairs
; Syntax ........: _CfgSectionWriteArray($_sCfg, $_sSection, $_aKeyVal)
; Parameters ....: $_sCfg - Path of the config file
; $_sSection - Section to write the key-value-pairs
; $_aKeyVal - 2D array Default: [[count_keys,section_name],[key_1,val],[key_2,val],...[key_n,val]]
; or [[key_1,val],[key_2,val],...[key_n,val]] - $_1stIndex must set to "0" in this case!
; $_1stIndex - [optional] The first index with data of the passed array. Default=1, like returned from _CfgSectionGetArray()
; Return values .: Success 1
; Failure 0, set @error 1 - $_aKeyVal is'nt a array
; 0, set @error 2 - $_aKeyVal is'nt a 2D array
; Author ........: BugFix
; ===============================================================================================================================
Func _CfgSectionWriteArray($_sCfg, $_sSection, $_aKeyVal, $_1stIndex=1)
Local $fH, $aSec = __CfgSectionRead($_sCfg, $_sSection)
Local $iErr = @error
If Not IsArray($_aKeyVal) Then Return SetError(1,0,0)
If UBound($_aKeyVal, 0) <> 2 Then Return SetError(2,0,0)
Local $sSectionContent = $_sSection
For $i = $_1stIndex To UBound($_aKeyVal) -1
$sSectionContent &= StringFormat(';%s=%s', $_aKeyVal[$i][0], $_aKeyVal[$i][1])
Next
Switch $iErr
Case 0 ; section exists
Return __CfgSectionWrite($_sCfg, $sSectionContent, $aSec[0])
Case 1 ; file does'nt exist
Return FileWrite($_sCfg, $sSectionContent & @CRLF)
Case 2 ; file is empty
$fH = FileOpen($_sCfg, 2) ; $FO_OVERWRITE (2)
FileWrite($fH, $sSectionContent & @CRLF)
Return FileClose($fH)
Case 3 ; section does'nt exist
Return __CfgSectionWrite($_sCfg, $sSectionContent & @CRLF, $aSec[0])
EndSwitch
EndFunc ;==>_CfgSectionWriteArray
#region - Helper functions
; Builds the new section content
Func __CfgKeyWrite($_sSection, $_sSectionContent, $_sKey, $_sValue)
Local $aSectionLine = StringSplit($_sSectionContent, ';', 2) ; $STR_NOCOUNT (2)
If @error = 1 Then ; none key-value-pairs in this line
$_sSectionContent = StringFormat('%s;%s=%s', $_sSection, $_sKey, $_sValue)
EndIf
$_sSectionContent = $_sSection
Local $aKeyVal, $bReplaced = False
For $i = 1 To UBound($aSectionLine) -1
$aKeyVal = StringSplit($aSectionLine[$i], '=', 2) ; $STR_NOCOUNT (2)
If $aKeyVal[0] = $_sKey Then
$_sSectionContent &= StringFormat(';%s=%s', $aKeyVal[0], $_sValue)
$bReplaced = True
Else
$_sSectionContent &= StringFormat(';%s=%s', $aKeyVal[0], $aKeyVal[1])
EndIf
Next
; the key is new:
If Not $bReplaced Then $_sSectionContent &= StringFormat(';%s=%s', $_sKey, $_sValue)
Return $_sSectionContent
EndFunc ;==>__CfgKeyWrite
; Returns an array: [line_number_in_file,line_content]
Func __CfgSectionRead($_sCfg, $_sSection)
Local $aRet[] = [0,''] ; if not found: line number is 0
If Not FileExists($_sCfg) Then Return SetError(1,0,$aRet)
Local $aCfg = FileReadToArray($_sCfg)
If @error = 2 Then Return SetError(2,0,$aRet) ; empty file
Local $aMatch
For $i = 0 To UBound($aCfg) -1
$aMatch = StringRegExp($aCfg[$i], "^([^;]+)", 1)
If $aMatch[0] = $_sSection Then
$aRet[0] = $i+1
$aRet[1] = $aCfg[$i]
Return $aRet
EndIf
Next
Return SetError(3,0,$aRet) ; section does'nt exist
EndFunc ;==>__CfgSectionRead
; Writes the full section in the passed line (overwriting). Line number 0 for append.
Func __CfgSectionWrite($_sCfg, $_sSectionContent, $_iSectionLine=0)
If $_iSectionLine = 0 Then ; section does'nt exist
Local $fH = FileOpen($_sCfg, 1) ; $FO_APPEND (1)
FileWrite($fH, $_sSectionContent)
Return FileClose($fH)
EndIf
Return __FileWriteToLine($_sCfg, $_iSectionLine, $_sSectionContent, True)
EndFunc ;==>__CfgSectionWrite
; Deletes the passed line
Func __CfgSectionDelete($_sCfg, $_iSectionLine)
Return __FileWriteToLine($_sCfg, $_iSectionLine, '', True)
EndFunc ;==>__CfgSectionDelete
; #FUNCTION# ====================================================================================================================
; Author ........: cdkid
; Modified.......: partypooper, MrCreatoR
; BugFix: The last line needs normally also a CRLF. So here is a new parameter to define this.
; ===============================================================================================================================
Func __FileWriteToLine($sFilePath, $iLine, $sText, $bOverWrite = False, $bLastLineCRLF = True)
If $iLine <= 0 Then Return SetError(4, 0, 0)
If Not IsString($sText) Then
$sText = String($sText)
If $sText = "" Then Return SetError(6, 0, 0)
EndIf
If $bOverWrite = Default Then $bOverWrite = False
If Not (IsBool($bOverWrite) Or $bOverWrite = 0 Or $bOverWrite = 1) Then Return SetError(5, 0, 0) ; For old versions.
If Not FileExists($sFilePath) Then Return SetError(2, 0, 0)
Local $aArray = FileReadToArray($sFilePath)
Local $iUBound = UBound($aArray) - 1
If ($iUBound + 1) < $iLine Then Return SetError(1, 0, 0)
Local $hFileOpen = FileOpen($sFilePath, FileGetEncoding($sFilePath) +2) ; $FO_OVERWRITE (2)
If $hFileOpen = -1 Then Return SetError(3, 0, 0)
Local $sData = ""
$iLine -= 1 ; Now the array is 0-based, so reduce the line number by 1.
For $i = 0 To $iUBound
If $i = $iLine Then
If $bOverWrite Then
If $sText Then $sData &= $sText & @CRLF
Else
$sData &= $sText & @CRLF & $aArray[$i] & @CRLF
EndIf
ElseIf $i < $iUBound Then
$sData &= $aArray[$i] & @CRLF
ElseIf $i = $iUBound Then
$sData &= $aArray[$i] & ($bLastLineCRLF ? @CRLF : '')
EndIf
Next
FileWrite($hFileOpen, $sData)
FileClose($hFileOpen)
Return 1
EndFunc ;==>__FileWriteToLine
#endregion
Alles anzeigen