Programmablauf beschleunigen, Datei Extraction

  • Guten Morgen,
    ich würde gern mein Programm scheller arbeiten lassen und habe diesbezüglich ein paar Fragen an Euch.

    1.gibt es noch andere Methoden ausser den beiden hier ?
    2.wie kann ich den Ablauf beschleunigen ?
    3.wer hilft mir für einen virtuellen Kaffe sowie ein Danke schön weiter :love:

    Hier meine bisherigen Versuche:

    Spoiler anzeigen
    [autoit]

    ;####################################################################
    ; Beschreibung was gemacht werden soll
    ;####################################################################
    ; aus einer großen datei sollen viele kleine dateien extraiert werden
    ; die start/end position jeder datei ist in einem array gespeichert
    ; in einer schleife werden die dateien nach und nach extraiert.
    ;
    ; $ByteStart = anfangsstelle in byte d an der extraiert werden soll
    ; $ByteLenght = länge in byte die extraiert werden soll
    ; z.B.
    ; $ByteStart = 1450424
    ; $ByteLenght = 69473
    ; oder
    ; $ByteStart = 6594465
    ; $ByteLenght = 77768

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;####################################################################
    ; die bisher schnellste version beim extraieren der dateien
    ; stürzt aber bei dateien die ein paar 100mb groß sind mit einem
    ; memory fehler ab (Error allocating memory)
    ; darum einen anderen Weg gesucht und gefunden, leider ist der langsamer
    ;####################################################################
    ; lese zu extraierende datei ein
    ; diese funktion bringt bei dateien um 500mb einen speicherfehler = crash
    $hFile = FileOpen($PACKFile, 16)
    $bData = FileRead($hFile)
    FileClose($hFile)

    [/autoit] [autoit][/autoit] [autoit]

    For $r = 0 to UBound($split,1) - 1
    ;eine datei wird aus dem buffer der hauptdatei "kopiert"
    $LogData = BinaryMid($bData, $ByteStart, $ByteLenght)
    ;die "kopierte" datei wird neu gespeichert
    $hFile = FileOpen($Foldername & "\" & $Filename& ".log", 18)
    FileWrite($hFile,$LogData)
    FileClose($hFile)
    ENDIF
    Next
    ;####################################################################
    ; diese funktioniert auch mit dateien die ein paar 100mb groß sind,
    ; ist aber leider extrem langsamer als die erste.
    ;####################################################################
    For $r = 0 to UBound($split,1) - 1
    ;lese die bytes der zu extraierenden datei ein
    $tBuffer = DllStructCreate("byte[" & $ByteLenght & "]")
    $hFile = _WinAPI_CreateFile($PACKFile, 2, 2)
    _WinAPI_SetFilePointer($hFile, $ByteStart)
    _WinAPI_ReadFile($hFile, DllStructGetPtr($tBuffer),$ByteLenght, $nBytes)
    _WinAPI_CloseHandle($hFile)

    [/autoit] [autoit][/autoit] [autoit]

    ;speichere die extraierten bytes als neue datei
    $hFile = _WinAPI_CreateFile($NewFolderName & "\" & $Filename& ".log", 1, 4)
    _WinAPI_SetFilePointer($hFile, 0,0)
    _WinAPI_WriteFile($hFile, DllStructGetPtr($tBuffer),$ByteLenght, $nBytes)
    _WinAPI_CloseHandle($hFile)
    $tBuffer = 0
    Next
    ;####################################################################

    [/autoit]

    Einmal editiert, zuletzt von JaneDoe (15. Februar 2011 um 07:44)

  • Hallo JaneDoe,

    herzlich willkommen im Forum und viel Spass mit AutoIt.

    Hier kannst du dir die deutsche Hilfe herunterladen.
    Hier gibt es ein AutoIt-Tutorial: http://wiki.autoit.de/wiki/index.php/TutorialSehr hilfreich ist auch das Buch von peethebee

    Edit: Das EndIf in Zeile 37 ist defintiv falsch, ansonsten kann ich in dem Schnipsel keinen Fehler erkennen, poste doch bitte ein zusammenhängedes Skript in dem der Fehler auftritt,

    mfg autoBert

    Einmal editiert, zuletzt von autoBert (15. Februar 2011 um 07:53)

  • [autoit]

    $bData = FileRead($hFile)

    [/autoit]

    Du liest die ganze Datei direkt in den Speicher obwohl du nur einen kleinen Teil der Datei brauchst?
    Sieh dir FileSetPos an und geh in kleineren Blöcken mit FileRead über deinen Bereich und schreib das ganze blockweise in deine neue Datei.
    So hast du nie mehr als die Blockgröße in deinem Speicher.

    [autoit]

    For $r = 0 to UBound($split,1) - 1

    [/autoit]

    Wo kommt das her - was ist das?

  • Zitat

    Wo kommt das her - was ist das?

    [autoit]

    For $r = 0 to UBound($split,1) - 1

    [/autoit]


    Wie beschrieben sind die Einträge Start/Ende Position der Dateien in einem Array.
    Das lasse ich mit UBound durchlaufen, bis ich am Ende vom Array angekommen bin = alle Dateien extraiert.

    Zitat

    Sieh dir FileSetPos an und geh in kleineren Blöcken mit FileRead über deinen Bereich und schreib das ganze blockweise in deine neue Datei.
    So hast du nie mehr als die Blockgröße in deinem Speicher.

    Danke, das wäre ein Versuch wert.
    Hoffe das wird dadurch nicht auch so langsam wie Methode 2.
    Rufe ja dann ständig die Hauptdatei auf, suche die Blöcke Häppchenweise zusammen und speicher dann *hm*

  • Also nach dem letzten Beitrag bin ich etwas verwirrt .... trotzdem mal ein simpler Ansatz.

    Spoiler anzeigen
    [autoit]

    $sFile = @ScriptDir & "\test.txt"
    $sFolder = @ScriptDir & "\splitt"
    If Not FileExists($sFolder) Then DirCreate($sFolder)
    $ByteStart = 0
    $iParts = 4
    $ByteLenght = 50

    [/autoit] [autoit][/autoit] [autoit]

    $hFile = FileOpen($sFile, 16)
    For $i = 1 To $iParts
    FileSetPos($hFile, $ByteStart * 1, 0)
    $LogData = FileRead($hFile, $ByteLenght)
    ConsoleWrite(BinaryToString($LogData) & @CRLF)
    $hFileTmp = FileOpen($sFolder & "\" & "part_" & $i & ".log", 18)
    FileWrite($hFileTmp, $LogData)
    FileClose($hFileTmp)
    $ByteStart += $ByteLenght
    Next
    FileClose($hFile)

    [/autoit]


    Hier werden lediglich 4 Dateien erstellt. Der Rest der Quelldatei wird ignoriert.

  • autoBert:
    Schau dir mal die Hilfe zu _WinAPI_CreateFile an... damit kann man auch vorhandene Dateien zum lesen öffnen.
    Der Name "CreateFile" ist wohl etwas ungeschickt gewählt, aber dafür ist Microsoft verantwortlich. ;)

    Wer andern eine Bratwurst brät
    der hat ein Bratwurstbratgerät.