- Offizieller Beitrag
Da diese Frage aufgetaucht war, habe ich mal eine Alternative auf Tag-Basis erstellt mit allen bekannten Ini-Funktionen in exakt derselben Funktionalität.
Ich habe hierbei bewußt auf die Verwendung von RegEx verzichtet um größtmögliche Vielfalt in Schlüssel und Wert zuzulassen.
Vielleicht kann es jemand brauchen.
Spoiler anzeigen
#include-once
#include <File.au3>
#include <String.au3>
#cs ===== Funktionsliste =======================================================
[/autoit] [autoit][/autoit] [autoit]Erstellen / Verwalten von Schlüssel-Wert-Paaren ohne INI-Größenlimit
[/autoit] [autoit][/autoit] [autoit]Musterdatei:
<sec>Sektion 1
<key>Schlüssel 1_1<val>Wert 1_1</val></key>
<key>Schlüssel 1_2<val>Wert 1_2</val></key>
<key>Schlüssel 1_3<val>Wert 1_3</val></key>
<key>Schlüssel 1_4<val>Wert 1_4</val></key>
</sec>
Funktionen sind identisch zu den bekannten Standard-Ini-Funktionen
[/autoit] [autoit][/autoit] [autoit]_IniEx_ReadSectionNames
_IniEx_ReadSection
_IniEx_Read
_IniEx_RenameSection
_IniEx_Write
_IniEx_WriteSection
#ce ============================================================================
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit];===============================================================================
; Function Name..: _IniEx_ReadSectionNames
; Description....: Liest die Sektionsnamen der IniEx-Datei aus
; Parameter(s)...: $sPath Pfad zur IniEx-Datei
; Return Value(s): Erfolg Array mit den Sektionsnamen, Anzahl in Array[0]
; Fehler 0 @error 1 - Datei nicht gefunden
; Author(s)......: BugFix ([email='bugfix@autoit.de'][/email])
;===============================================================================
Func _IniEx_ReadSectionNames($sPath)
If Not FileExists($sPath) Then Return SetError(1, 0, 0)
Local $sRead = FileRead($sPath)
Local $aSec = _StringBetween($sRead, '<sec>', @CRLF)
Local $aOut[UBound($aSec) + 1]
$aOut[0] = UBound($aSec)
For $i = 0 To UBound($aSec) - 1
$aOut[$i + 1] = $aSec[$i]
Next
Return $aOut
EndFunc ;==>_IniEx_ReadSectionNames
;===============================================================================
; Function Name..: _IniEx_ReadSection
; Description....: Liest die angegebene Sektion aus
; Parameter(s)...: $sPath Pfad zur IniEx-Datei
; $sSection Sektionsname
; Return Value(s): Erfolg 2D-Array, Array[0][0] enthält Anzahl, [n][0]=Key, [n][1]=Value
; Fehler 0 @error 1 - Datei nicht gefunden
; Author(s)......: BugFix ([email='bugfix@autoit.de'][/email])
;===============================================================================
Func _IniEx_ReadSection($sPath, $sSection)
If Not FileExists($sPath) Then Return SetError(1, 0, 0)
Local $fInSection = False, $aIni, $iKeys = 0, $aPairs[1][2] = [[$iKeys]], $aKeyVal, $sKeyVal
_FileReadToArray($sPath, $aIni)
For $i = 1 To $aIni[0]
If Not $fInSection And $aIni[$i] <> '<sec>' & $sSection Then ContinueLoop
$fInSection = True
If $aIni[$i] = '</sec>' Then ExitLoop
If StringLeft($aIni[$i], 5) = '<key>' Then
$aKeyVal = _StringBetween($aIni[$i], '<key>', '</val></key>')
If @error Then ContinueLoop
$aKeyVal = StringSplit($aKeyVal[0], '<val>', 3)
$iKeys += 1
ReDim $aPairs[$iKeys + 1][2]
$aPairs[0][0] = $iKeys
$aPairs[$iKeys][0] = $aKeyVal[0]
$aPairs[$iKeys][1] = $aKeyVal[1]
EndIf
Next
Return $aPairs
EndFunc ;==>_IniEx_ReadSection
;===============================================================================
; Function Name..: _IniEx_Read
; Description....: Liest den Wert für den Schlüssel einer Sektion aus
; Parameter(s)...: $sPath Pfad zur IniEx-Datei
; $sSection Sektionsname
; $sKey Schlüsselname
; $sDefault Defaultwert, wenn Key nicht gefunden
; Return Value(s): Erfolg Wert des Schlüssels
; Fehler 0 @error 1 - Datei nicht gefunden
; Author(s)......: BugFix ([email='bugfix@autoit.de'][/email])
;===============================================================================
Func _IniEx_Read($sPath, $sSection, $sKey, $sDefault = 'Default')
If Not FileExists($sPath) Then Return SetError(1, 0, 0)
Local $fInSection = False, $aIni, $iKeys = 0, $aPairs[1][2] = [[$iKeys]], $aKeyVal, $sKeyVal
_FileReadToArray($sPath, $aIni)
For $i = 1 To $aIni[0]
If Not $fInSection And $aIni[$i] <> '<sec>' & $sSection Then ContinueLoop
$fInSection = True
If $aIni[$i] = '</sec>' Then ExitLoop
If StringLeft($aIni[$i], 5) = '<key>' Then
$aKeyVal = _StringBetween($aIni[$i], '<key>', '</val></key>')
If @error Then ContinueLoop
$aKeyVal = StringSplit($aKeyVal[0], '<val>', 3)
If $aKeyVal[0] = $sKey Then Return $aKeyVal[1]
EndIf
Next
Return $sDefault
EndFunc ;==>_IniEx_Read
;===============================================================================
; Function Name..: _IniEx_RenameSection
; Description....: Umbenennen einer Sektion
; Parameter(s)...: $sPath Pfad zur IniEx-Datei
; $sSection Sektionsname
; $sNewSection neuer Sektionsname
; $fOverwrite falls sNewSection bereits besteht wird Inhalt gelöscht, Standard=False
; Return Value(s): Erfolg 1
; Fehler 0 @error 1 - Datei nicht gefunden
; 2 - Sektionsname existiert nicht
; 3 - Sektion existiert aber Überschreib-Flag nicht gesetzt
; Author(s)......: BugFix ([email='bugfix@autoit.de'][/email])
;===============================================================================
Func _IniEx_RenameSection($sPath, $sSection, $sNewSection, $fOverwrite = False)
If Not FileExists($sPath) Then Return SetError(1, 0, 0)
Local $fExists = False, $fInSection = False, $aIni, $iFirstLine = 0, $iLastLine
_FileReadToArray($sPath, $aIni)
For $i = 1 To $aIni[0] ; check ob $sNewSection bereits existiert
If $aIni[$i] = '<sec>' & $sNewSection Then
$fExists = True
ExitLoop
EndIf
Next
For $i = 1 To $aIni[0]
If Not $fInSection And $aIni[$i] = '<sec>' & $sSection Then ; Sektion Startzeile suchen
$fInSection = True
$iFirstLine = $i
ContinueLoop
EndIf
If $fInSection And Not $fExists Then ExitLoop ; $sNewSection existiert noch nicht >> Endzeile braucht nicht ermittelt werden
If $fInSection And $aIni[$i] = '</sec>' Then ; Sektion Endzeile suchen
$iLastLine = $i
$fInSection = False
ExitLoop
EndIf
Next
If $iFirstLine = 0 Then Return SetError(2, 0, 0) ; Sektionsname nicht enthalten
If Not $fExists Then Return _FileWriteToLine($sPath, $iFirstLine, '<sec>' & $sNewSection, 1)
If $fExists And Not $fOverwrite Then
Return SetError(3, 0, 0) ; $sNewSection existiert aber Überschreib-Flag nicht gesetzt
Else ; alte Sektion kpl. löschen
For $i = $iLastLine To $iFirstLine Step -1
_FileWriteToLine($sPath, $iFirstLine, '', 1)
Next
EndIf
_FileReadToArray($sPath, $aIni)
For $i = 1 To $aIni[0]
If Not $fInSection And $aIni[$i] = '<sec>' & $sNewSection Then ; Sektion Startzeile suchen
$fInSection = True
$iFirstLine = $i
ContinueLoop
EndIf
If Not $fExists Then ExitLoop ; $sNewSection existiert noch nicht >> Endzeile braucht nicht ermittelt werden
If $fInSection And $aIni[$i] = '</sec>' Then ; Sektion Endzeile suchen
$iLastLine = $i
$fInSection = False
ExitLoop
EndIf
Next
For $i = $iLastLine - 1 To $iFirstLine + 1 Step -1 ; Sektion mit selbem Namen, wie $sNewSection leeren
_FileWriteToLine($sPath, $i, '', 1)
Next
Return 1
EndFunc ;==>_IniEx_RenameSection
;===============================================================================
; Function Name..: _IniEx_Write
; Description....: Schreibt einen neuen Wert in einen Schlüssel oder fügt ein neues Schlüssel-Wert-Paar ein
; Parameter(s)...: $sPath Pfad zur IniEx-Datei
; $sSection Sektionsname
; $sKey Schlüsselname
; $sValue Wert
; Return Value(s): Erfolg Letzter Wert des Schlüssels, bei Neuanlage Leerstring
; Fehler 0 @error 1 - Datei nicht gefunden
; 2 - Sektion existiert nicht
; Author(s)......: BugFix ([email='bugfix@autoit.de'][/email])
;===============================================================================
Func _IniEx_Write($sPath, $sSection, $sKey, $vValue)
If Not FileExists($sPath) Then Return SetError(1, 0, 0)
Local $fInSection = False, $aIni, $aKeyVal, $vOldVal = '', $fKeyNew = False, $iKeyLine = 0
_FileReadToArray($sPath, $aIni)
For $i = 1 To $aIni[0]
If Not $fInSection And $aIni[$i] = '<sec>' & $sSection Then ; Sektion Startzeile suchen
$fInSection = True
ContinueLoop
EndIf
If $fInSection And StringLeft($aIni[$i], 5) = '<key>' Then
$aKeyVal = _StringBetween($aIni[$i], '<key>', '</val></key>')
$aKeyVal = StringSplit($aKeyVal[0], '<val>', 3)
If $aKeyVal[0] = $sKey Then
$iKeyLine = $i
$vOldVal = $aKeyVal[1]
ExitLoop
EndIf
EndIf
If $fInSection And $aIni[$i] = '</sec>' Then ; Sektionsende
If $iKeyLine = 0 Then
$fKeyNew = True
$iKeyLine = $i
EndIf
ExitLoop
EndIf
Next
If Not $fInSection Then Return SetError(2, 0, 0) ; Sektion existiert nicht
If $fKeyNew Then
_FileWriteToLine($sPath, $iKeyLine, '<key>' & $sKey & '<val>' & $vValue & '</val></key>')
Else
_FileWriteToLine($sPath, $iKeyLine, '<key>' & $sKey & '<val>' & $vValue & '</val></key>', 1)
EndIf
Return $vOldVal ; Rückgabe alter Wert
EndFunc ;==>_IniEx_Write
;===============================================================================
; Function Name..: _IniEx_WriteSection
; Description....: Schreibt eine Sektion in die IniEx-Datei
; Parameter(s)...: $sPath Pfad zur IniEx-Datei
; $sSection Sektionsname
; $vData String (Schlüssel=Wert, mehrere mit @LF trennen) oder Array [n][0]= Schlüssel, [n][1]= Wert
; $iIndex Falls Array übergeben, der Startindex (Default=1)
; Return Value(s): Erfolg 1
; Fehler 0 @error 1 - Datei nicht gefunden
; 2 - kein 2D-Array übergeben
; Author(s)......: BugFix ([email='bugfix@autoit.de'][/email])
;===============================================================================
Func _IniEx_WriteSection($sPath, $sSection, $vData, $iIndex = 1)
If Not FileExists($sPath) Then Return SetError(1, 0, 0)
Local $aIni, $aTmp, $aSplit, $aData[1][2] = [[0]], $sSectionData
Local $fInSection = False, $iFirstLine = 0, $iLastLine, $sRead, $fh
If Not IsArray($vData) Then ; Daten in Array packen
$aTmp = StringSplit($vData, @LF, 1)
ReDim $aData[$aTmp[0] + 1][2]
$aData[0][0] = $aTmp[0]
For $i = 1 To $aTmp[0]
$aSplit = StringSplit($aTmp[$i], '=')
$aData[$i][0] = $aSplit[1]
$aData[$i][1] = $aSplit[2]
Next
Else
If UBound($aData, 2) <> 2 Then Return SetError(2, 0, 0)
$aData = $vData
EndIf
_FileReadToArray($sPath, $aIni)
For $i = 1 To $aIni[0] ; check ob $sSection bereits existiert
If $aIni[$i] = '<sec>' & $sSection Then
$iFirstLine = $i
$fInSection = True
EndIf
If $fInSection And $aIni[$i] = '</sec>' Then ; Sektion Endzeile suchen
$iLastLine = $i
$fInSection = False
EndIf
Next
$sSectionData = '<sec>' & $sSection & @CRLF ; zu schreibenden Sektions-String zusammenstellen
For $i = $iIndex To UBound($aData) - 1
$sSectionData &= '<key>' & $aData[$i][0] & '<val>' & $aData[$i][1] & '</val></key>' & @CRLF
Next
$sSectionData = $sSectionData & '</sec>'
If $iFirstLine > 0 Then ; Sektion besteht bereits
For $i = $iLastLine To $iFirstLine + 1 Step -1
_FileWriteToLine($sPath, $iFirstLine, '', 1)
Next
Return _FileWriteToLine($sPath, $iFirstLine, $sSectionData, 1) ; Sektion neu schreiben
Else ; neue Sektion am Ende anfügen
$fh = FileOpen($sPath, 1)
FileWrite($fh, @CRLF & $sSectionData)
Return FileClose($fh)
EndIf
EndFunc ;==>_IniEx_WriteSection