- Offizieller Beitrag
Nunja, nachdem ich mich mehr mit den DllStruct-Funktionen beschäftigen wollte, habe ich mal zwei Funktionen zum lesen/schreiben von Arrays auf Festplatte erstellt.
Der Vorteil ist, dass man damit ohne Trennzeichen auskommt. Im Array dürfen also alle 256 ASCII-Zeichen (0...255) vorkommen.
Vielleicht können mal die Profis in Sachen Dll-Struct über das Script schauen, ob man da noch was verbessern kann. Im Moment dauert das laden länger als das speichern der Daten.
Ich bin schon froh, dass ich das soweit zum laufen bekommen habe. Nachdem ich einige Zeit gebraucht habe, zu merken, dass "_WinAPI_WriteFile" die Daten immer auf DWORD-Länge "aufrundet".
AutoIt
#include <Array.au3>
#include <File.au3>
#include <FileConstants.au3>
#include <WinAPI.au3>
#include <WinAPIError.au3>
Global $sPath = StringRegExpReplace(@AutoItExe, '(.+\\).+', '$1')
Global $array = _FileListToArrayRec($sPath, '*', $FLTAR_FILES, $FLTAR_RECUR, $FLTAR_SORT, $FLTAR_FULLPATH)
_ArrayDisplay($array, 'Dieses Array wird gespeichert')
$iTimer = TimerInit()
Global $sfile = @ScriptDir & '\test.bin'
_ArraySave($array, $sfile)
ConsoleWrite('Error: ' & @error & ' Time: ' & TimerDiff($iTimer) & @CR)
$iTimer = TimerInit()
Global $aNew = _ArrayLoad($sfile)
ConsoleWrite('Error: ' & @error & ' Time: ' & TimerDiff($iTimer) & @CR)
_ArrayDisplay($aNew, 'Geladenes Array')
Exit
Func _ArraySave(ByRef $avArray, $sSavefile)
If Not IsArray($avArray) Then Return SetError(1, 0, False)
Local $nBytes, $iLen = 0, $iError = 0, $tHEADER, $tDATA, $iArrayCount = UBound($avArray)
Local $hFile = _WinAPI_CreateFile($sSavefile, 1, 4) ; 1 = Create a new file (overwrite), 4 = Write-Mode
If $hFile = 0 Then Return SetError(2, 0, False)
$tHEADER = DllStructCreate('struct;char Type[8];uint Cnt;endstruct')
DllStructSetData($tHEADER, 'Type', 'Au3Array')
DllStructSetData($tHEADER, 'Cnt', $iArrayCount)
If _WinAPI_WriteFile($hFile, DllStructGetPtr($tHEADER), DllStructGetSize($tHEADER), $nBytes) Then
For $i = 0 To $iArrayCount - 1
$iLen = StringLen($avArray[$i])
$tDATA = DllStructCreate('struct;uint Size;char Data[' & $iLen & '];endstruct')
DllStructSetData($tDATA, 'Size', $iLen)
DllStructSetData($tDATA, 'Data', $avArray[$i])
If Not _WinAPI_WriteFile($hFile, DllStructGetPtr($tDATA), DllStructGetSize($tDATA), $nBytes) Then
$iError = _WinAPI_GetLastError()
$tDATA = 0
ExitLoop
EndIf
$tDATA = 0
Next
Else
$iError = _WinAPI_GetLastError()
EndIf
$tHEADER = 0
_WinAPI_CloseHandle($hFile)
Return SetError($iError, 0, $iError = 0)
EndFunc
Func _ArrayLoad($sLoadfile)
Local $hFile, $tHEADER, $nBytes, $sType, $iArrayCount, $iError = 0, $iSize, $tDATA
$hFile = _WinAPI_CreateFile($sLoadfile, 2, 2) ; 2 = FileOpen, 2 = Read-Mode
If $hFile = 0 Then Return SetError(1, 0, False)
$tHEADER = DllStructCreate('struct;char Type[8];uint Cnt;endstruct')
_WinAPI_ReadFile($hFile, DllStructGetPtr($tHEADER), DllStructGetSize($tHEADER), $nBytes)
$sType = DllStructGetData($tHEADER, 'Type')
If $sType = 'Au3Array' Then
$iArrayCount = DllStructGetData($tHEADER, 'Cnt')
Local $avArray[$iArrayCount]
Local $tSIZE = DllStructCreate('struct;uint Size;endstruct')
For $i = 0 To $iArrayCount - 1
If Not _WinAPI_ReadFile($hFile, DllStructGetPtr($tSIZE), DllStructGetSize($tSIZE), $nBytes) Then
$iError = _WinAPI_GetLastError()
ExitLoop
EndIf
$iSize = DllStructGetData($tSIZE, 'Size')
If Mod($iSize, 4) Then ; 1...3 Füllbytes wegen DWORD-Länge der Einträge
$tDATA = DllStructCreate('struct;char Data[' & $iSize & '];byte[' & 4 - Mod($iSize, 4) & '];endstruct')
Else
$tDATA = DllStructCreate('struct;char Data[' & $iSize & '];endstruct')
EndIf
If Not _WinAPI_ReadFile($hFile, DllStructGetPtr($tDATA), DllStructGetSize($tDATA), $nBytes) Then
$iError = _WinAPI_GetLastError()
$tDATA = 0
ExitLoop
EndIf
$avArray[$i] = DllStructGetData($tDATA, 'Data')
$tDATA = 0
Next
EndIf
_WinAPI_CloseHandle($hFile)
$tSIZE = 0
$tHEADER = 0
If $iError Then Return SetError($iError, 0, False)
Return $avArray
EndFunc
Alles anzeigen