TXT Datei spinnt.....

  • Guten Tag oder Abend je nach dem wann ihr reinschaut

    Also wie ihr an dem Script-ausschnitt sehen werdet geht es darum das ich eine Datenbank für videos machen möchte.
    Das Problem ist der Abschnitt in dem die Liste erstellt wird
    _RunDos ('cmd.exe /u /c dir "' & $Path & '" /a-d /s /b * >"' & $Liste & '"')

    denn der Txt der ausgegeben wird lässt sich nicht benutzen
    jetzt werden vielleicht einige fragen warum mit _runDos
    testet es mal es ist im verhältnis zum recusiven durchsuche der festplatte deutlich schneller daher möchte ich es gerne auf diesen Weg versuchen.
    ich glaube das es vielleicht mit der Kodierung der Txt zu tun hat denn ich habe sie mal geöffnet und dann unter Speichern unter mit Datentyp: alle Dateien gespeichert und
    so hat es funktioninert nun möchte ich aber ganz gerne es so laufen lassen ohne die txt jedesmal von Hand umzuspeichern

    ich bedanke mich schon mal für das Interese und bin für jeden Ratschlag Dankbar der mich weiterbringt.


    [autoit]

    Func _DB_ReFreash ()
    Local $Path = FileSelectFolder ("","") FileDelete ($Liste) _RunDos ('cmd.exe /u /c dir "' & $Path & '" /a-d /s /b * >"' & $Liste & '"')EndFunc
    Func _DB_CHK () If Not FileExists ($Liste) Then _DB_ReFreash ()Local $sDrive, $sDir, $sFilename, $sExtensionLocal $C = _FileCountLines ($Liste)Local $STRG_Video_Format = "mp4;avi;Mpeg;flv;mv4;divx;xivd;wmv;mov;qt;m2ts;mts;vob;evo;webm;mkv;mka;asf;mpg;ps;rm;rmvb;dv;3gp"Local $AR_Video_Format = StringSplit ($STRG_Video_Format, ";")Local $AR_Video[1], $AR_DIR[1]Local $AR_List = FileReadToArray ($Liste)Local $AR_List_Out[UBound ($AR_List)][3];~ _ArrayDisplay ($AR_List)Local $Var = 0For $1 = 0 to UBound ($AR_List)-1 For $2 = 1 To $AR_Video_Format[0] $PS = _PathSplit ($AR_List[$1], $sDrive, $sDir, $sFilename, $sExtension);~ _ArrayDisplay ($PS, "PS") If $PS[4] = "." & $AR_Video_Format[$2] Then $Var = $Var + 1 $AR_List_Out[$Var][0] = $AR_List[$1] $AR_List_Out[$Var][1] = $PS[1] & $PS[2] $AR_List_Out[$Var][2] = $PS[3] EndIf Next
    Next _Array_Look ($AR_List_Out, "Video", "FullPath|Dir|Name") ;_Func.au3EndFunc

    [/autoit]

    Einmal editiert, zuletzt von DaveTDancer (23. Mai 2014 um 07:19)

  • Naja ob der Cmd-Dir-Befehl so extrem viel schneller ist wage ich zu bezweifeln.
    Kann aber jeder selbst testen:

    Simple-Cmd-Dir-Funktion im Vergleich
    [autoit]

    #include <Process.au3>
    #include <Array.au3>

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

    $s_Dir = "C:"

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

    $iT = TimerInit()
    $a_Array = ReadWithCmd($s_Dir & "\*.txt")
    ConsoleWrite(StringFormat("% 20s:\t%6.2f\n", "Cmd", TimerDiff($iT) / 1000))
    ;~ _ArrayDisplay($a_Array)

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

    $iT = TimerInit()
    $a_Array = FlwStrRek($s_Dir, "\.txt$", 1)
    ConsoleWrite(StringFormat("% 20s:\t%6.2f\n", "FlwStrRek", TimerDiff($iT) / 1000))
    ;~ _ArrayDisplay($a_Array)

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

    $iT = TimerInit()
    $a_Array = FLwStr($s_Dir, "\.txt$", 1)
    ConsoleWrite(StringFormat("% 20s:\t%6.2f\n", "FlwStr", TimerDiff($iT) / 1000))
    ;~ _ArrayDisplay($a_Array)

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

    Func ReadWithCmd($s_Path)
    Local $s_TempFile = @TempDir & "\CmdFileList.txt"
    FileDelete($s_TempFile)
    _RunDos('dir "' & $s_Path & '" /a-d /s /b * >"' & $s_TempFile & '"')
    Local $a_Array = FileReadToArray($s_TempFile)
    FileDelete($s_TempFile)
    Return ($a_Array)
    EndFunc ;==>ReadWithCmd

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

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: FLwStrRek
    ; Description ...: Gibt ein Array mit Dateien bzw. Unterordnern im gesamten Verzeichnisbaum zurück
    ; Syntax.........: FLwStrRek($sSD, [$sPat = '*', [$iF = 0]])
    ; Parameters ....: $sSD - Startverzeichnis (mehrere Verzeichnisse durch | trennen)
    ; $sPat - Optional: Pattern zur Filterung mit regulären Ausdrücken
    ; $iF - Optional: Flag ob nur Dateien, Ordner oder beides gesucht werden sollen
    ; |$iF=3(Default) Gibt beides zurück
    ; |$iF=1 Gibt nur Dateien zurück
    ; |$iF=2 Gibt nur Ordner zurück
    ; $flgSS - Art der Rückgabe (Siehe StringSplit()-Funktion)
    ; $bS - interner Rekursionsparameter - nicht verändern!
    ; Return values .: @Error: 1 = Startverzeichnis existiert nicht.
    ; |2 = ungültiger Wert für $iF
    ; Author ........: AspirinJunkie
    ; Modified.......: 12.04.2010
    ; Remarks .......:
    ; Related .......:
    ; Link ..........:
    ; Example .......: No
    ; Note ..........: basiert auf einem rekursiven Ansatz
    ; ===============================================================================================================================
    Func FlwStrRek($sSD, Const $sPat = '', Const $iF = 3, Const $flgSS = 2, Const $bS = True)
    ; By AspirinJunkie
    Local $FFFF, $FFNF, $aD
    Local Static $sRet, $hDLL
    If $bS Then
    $hDLL = DllOpen("kernel32.dll")
    If Not ($iF = 3 Or $iF = 1 Or $iF = 2) Then Return SetError(1, DllClose($hDLL), "")
    EndIf
    For $i In StringSplit($sSD, "|", 2)
    If StringRight($i, 1) = "" Then $i = StringTrimRight($i, 1)
    If Not FileExists($i) Then ContinueLoop
    $FFFF = FileFindFirstFile($i & "\*")
    If $FFFF <> -1 Then
    Do
    $FFNF = FileFindNextFile($FFFF)
    If @error Then ExitLoop
    If @extended Then
    If BitAND(StringRegExp($FFNF, $sPat) * 2, $iF) Then $sRet &= $i & "" & $FFNF & "|"
    $aD = DllCall($hDLL, "dword", "GetFileAttributesW", "wstr", $i & "" & $FFNF)
    If @error Or BitAND($aD[0], 0x400) Then ContinueLoop
    FlwStrRek($i & "" & $FFNF, $sPat, $iF, 2, False)
    ElseIf BitAND(StringRegExp($FFNF, $sPat), $iF) Then
    $sRet &= $i & "" & $FFNF & "|"
    EndIf
    Until 0
    FileClose($FFFF)
    EndIf
    Next
    If $bS Then
    DllClose($hDLL)
    Local $aRet = StringSplit(StringTrimRight($sRet, 1), "|", $flgSS)
    $sRet = ""
    Return $aRet
    EndIf
    EndFunc ;==>FlwStrRek

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

    ; #FUNCTION# ======================================================================================
    ; Name ..........: FLwStr()
    ; Description ...: Findet Dateien und/oder Ordner in einem Verzeichnisbaum
    ; Syntax ........: FLwStr($sSD, Const[ $sPat = '', Const[ $iF = 3]])
    ; Parameters ....: $sSD - Suchort (mehrere Suchorte durch | trennen)
    ; Const $sPat - [optional] regulärer Ausdruck für zu findende Datei/Ordnernamen (default:'')
    ; Const $iF - [optional] 1=nur Dateien, 2=nur Ordner, 3=Dateien+Ordner (default:3)
    ; Const $iSSFlag - [optional] 0=Rückgabearray mit Anzahl Elemente in $Array0, 2=Rückgabearray ohne Anzahl Elemente
    ; Return values .: Success - Return Array with Matches with $Array[0] = Count
    ; Failure - Return "" and set @error
    ; Author ........: AspirinJunkie
    ; Remarks .......: Funktionsweise ist iterativ - nicht rekursiv
    ; Example .......: Yes
    ; #include <Array.au3>
    ; $aTmp = FLwStr(@WindowsDir & '|' & @ProgramFilesDir, "^Temp$", 2)
    ; _ArrayDisplay($aTmp)
    ; =================================================================================================
    Func FLwStr($sSD, Const $sPat = '', Const $iF = 3, Const $iSSFlag = 0)
    ;by AspirinJunkie
    Local $sRet = "", $sSubD = ""
    For $i In StringSplit($sSD, '|', 2)
    If StringRight($i, 1) = '\' Then $i = StringTrimRight($i, 1)
    If Not FileExists($i) Then Return SetError(2, 0, "")
    $sSubD &= '|' & $i
    Next
    Local $FFFF, $FFNF, $sDir, $iC
    Local $aD, $hDLL = DllOpen('kernel32.dll')
    If Not ($iF = 3 Or $iF = 1 Or $iF = 2) Then Return SetError(3, 0, "")
    Do
    $iC = StringInStr($sSubD, '|', 2, -1)
    If @error Or $iC = 0 Then ExitLoop
    $iC = StringLen($sSubD) - $iC
    $sDir = StringRight($sSubD, $iC)
    $sSubD = StringTrimRight($sSubD, $iC + 1)
    $FFFF = FileFindFirstFile($sDir & '\*')
    If $FFFF <> -1 Then
    Do
    $FFNF = FileFindNextFile($FFFF)
    If @error Then ExitLoop
    If @extended Then
    If BitAND(StringRegExp($FFNF, $sPat) * 2, $iF) Then $sRet &= $sDir & '\' & $FFNF & '\|'
    $aD = DllCall($hDLL, 'dword', 'GetFileAttributesW', 'wstr', $sDir & '\' & $FFNF)
    If @error Or BitAND($aD[0], 0x400) Then ContinueLoop
    $sSubD &= '|' & $sDir & '\' & $FFNF
    ElseIf BitAND(StringRegExp($FFNF, $sPat), $iF) Then
    $sRet &= $sDir & '\' & $FFNF & '|'
    EndIf
    Until 0
    FileClose($FFFF)
    EndIf
    Until 0
    DllClose($hDLL)
    Return StringSplit(StringTrimRight($sRet, 1), '|', $iSSFlag)
    EndFunc ;==>FLwStr

    [/autoit]

    Bei dir sehe ich im ersten Blick ein Problem:
    _RunDos macht nichts weiter als ein RunWait.
    Nur das dem Befehl noch ein cmd.exe /C vorangestellt wird.
    Du rufst also cmd.exe /c cmd.exe /u /c dir ... auf.

  • Danke ersteinmal für dein Interesse und den Versuch mich zu läutern.
    Aber bei mir ist es im wesentlichen schneller als die Recursive variante gerade bei großen ordnern merke ich das

    Wie geasagt teste mal batch ausgabe als txt ordner mit unterordner das dauert selbst bei sehr großen ordnern nur wenige sec.
    wobei es bei der anderen Variante teilweise faste ne minute brauchte.

    mir würde es ja auch reichen wenn jemand mir erkläten könnte wie ich den runbefehl als Studread auslesen kann dann könnte ich es ja direkt über Autoit speichern und dann kann ich den text auch lesen.
    Aber irgendwie möchte ich schon gern wissen wie ich von CMD ausgegebene Dateien als text benutzten kann.
    Denn es gibt ja programme die geben auch per hintergrundBatch txt aus die ich so ja sonst nicht benutzten kann.
    entweder ich muss den Text konvertien, aber wie?
    oder eine andere variant.

  • Zu sagen die Textdatei spinnt ist schon sehr gewagt.
    Eine Textdatei enthält nur Informationen. Wenn du nicht die selbe Sprache sprichst kann die Textdatei nichts dafür :P

    Bestimmt hat es was mit der Kodierung zu tun. Du setzt ja diese Kodierung auch selbst (cmd.exe /u)
    Autoit default ist ANSI. Deswegen liefert dir FileReadToArray wahrscheinlich bei einigen Zeichen das falsche Ergebnis
    Abhilfe: verwende Fileopen, Filereadline und Fileclose statt FileReadToArray

    Auserdem ist deine Verschachtlung von cmd's mit _RunDos subobtimal (wie AspirinJunkie schon sagt)
    Mal davon abgesehn dass ich am Nutzen von _RunDos zweifle^^

  • Hast du natürlich recht das es nicht fair den Textdateien gegenüber ist
    aber irgendwie muss man ja auf sein Problem hinweisen.
    Fileopen fileread usw. Geben die selben infos raus.
    Aber wie schon erwähnt die Geschwindigkeit ist für mich das Kriterium es so zu versuchen.

    Aber versuche es jetzt mal mit dem cmdbefehl ob ich anders anpassen kann

  • Wie geasagt teste mal batch ausgabe als txt ordner mit unterordner das dauert selbst bei sehr großen ordnern nur wenige sec.
    wobei es bei der anderen Variante teilweise faste ne minute brauchte.


    Was ich dir mit meinem Beispielcode zeigen wollte war, dass es schlicht auf die Implementierung ankommt.
    Die beiden Funktionen die ich dir gepostet habe können von der Performance her mit der Batchvariante mithalten.
    Sie sind nur unwesentlich langsamer aber deutlich umfangreicher im Funktionsumfang.

    Zu deinem Problem mit den Textdateien:
    Ich gebe zu, dass ich zu faul bin deinen Code zu testen und auf den Fehler hin zu überprüfen.
    Kannst du vielleicht ein direkt lauffähiges Minimalsskript posten, dass jeder direkt bei sich ausführen kann und welches den Fehler reproduziert?
    Btw: Welchen Browser verwendest du? - dein jetziger versaut irgendwie die Zeilenumbrüche im Forum.

  • so testet es mal bitte, hoffe das ich so mit eurer Hilfe an die Lösung gelange wenn es (nur) die Text-Kodierung ist
    habt ihr ne möglichkeit die zu ändern.

    und zu der Geschwindigkeit muss ich sagen das es doppellt so lange braucht hab es mit dem script getestet
    mit CMD = 17 Sec
    recursiv = 37 Sec also schon merklich
    nichts desto trotz bin ich natürlich bereit auch diese Variant zu nutzten wenn es nicht anders geht.
    Aber vielleicht brauch ich die Txt datei ja auch net von Cmd ausgeben lassen kann mir jemand mal sagen ob ich die list auch per Studout ausgeben (Am besten mit Beispiel dann verstehhe ich es auch gleich) lassen kann
    weil ich sie ja dann gleich mit autoit schreiben kann und dann ist auch gut meine bisherigen Versuche gaben keine Ergebniss.


    Ich Danke aber schon mal wieder im vorraus für hilfe und Interresse

    [autoit][/autoit][autoit]

    [autoit]

    [/autoit]

    [/autoit]

    2 Mal editiert, zuletzt von DaveTDancer (22. Mai 2014 um 15:49)

  • Danke das ist es ja, Studread hab ich schon angeschaut bei anderen scripts ging es auch aber bei dem cmdbefehl bekomme ich keinen output daher war ja meine frage ob jemand weiß wie ich den obenstehenden Befehl auslesen kann wäre lieb halt mit nem kleinen Beispiel oder einen Verweiß auf einTutorial was mich weiterbring denn so mit meinem aktuellen Wissensstand stehe ich im Wald, warte auf den Bus und verstehe nur Bahnhof ;)

  • Ok machen wir es anders. Stdoutread bringt schon Text zurück aber halt auch wieder in Unicode.
    Wenn du wirklich dir nutzen willst dann würde ich dir vorschlagen den Output in eine Datei umzulenken und die dann mit Fileopen im Unicodemodus auszulesen.
    Beispiel:

    [autoit]

    #include <Array.au3>

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

    $Path = FileSelectFolder("","")
    $sOutputFile = @TempDir & '\test.txt'
    $pid = Run(@ComSpec & ' /u /c DIR "' & $Path & '" /a-d /s /b * > ' & $sOutputFile, $Path, @SW_HIDE)
    $hOpen = FileOpen($sOutputFile, 32)
    $sText = FileRead($hOpen)
    $aText = StringSplit(StringReplace($sText, @CR, ''), @LF)
    FileClose($hOpen)
    FileDelete($sOutputFile)
    _ArrayDisplay($aText)

    [/autoit]

    Wenn du wirklich sehr viele Daten in dem Pfad hast dann solltest du statt FileRead und Stringsplit lieber umsteigen auf filereadline in einer Schleife.

  • Also ich habe den Befehl etwas geändert dadurch funktioniert zumindest das einlesen von der Datenbank.txt

    [autoit]

    _RunDos ('cmd.exe /c dir "' & $Path & '" /a-d /s /b * >"' & $Liste & '"')

    [/autoit]


    trotzdem interessiert mich natürlich die Frage ob man das ganze auch mit Studread auslesen kann?

    Ich danke aber schon mal allen die mich unterstüzt haben oder mich in die richtige Richtung verwiesen haben.  :D
    Ich werde noch etwas warten ob noch jemand ne Idee hat ansonsten schließe ich den Thread natürlich.

  • Danke Schnitzel aber siehst ja das ich das mit "/u" jetzt rausgenommen habe hab das script auch nur Copy and past aus nem anderen script vo mir übernommen ohne zu checken das das /u für Unicode steht
    das ist aber hier in dem fall gar nett wichtig da es mir ja nur darum geht das die Datenbank.txt angelegt wird um sie einzulese in meine Gui.
    Deine IDEE hat mich auf jeden Fall weiter gebracht
    aber selbst wenn ich das /u weglasse erhalte ich keine ausgabe über Stdoutread oder ich mach immer noch was falsch

  • _Rundos macht nichts anderes als die cmd.exe per RunWait mit dem übergebenen Befehl auszuführen.
    Du machst also

    [autoit]

    'cmd.exe /c cmd.exe /c dir "' & $Path & '" /a-d /s /b * >"' & $Liste & '"'

    [/autoit]


    Das ist das was AspirinJunkie schon zu anfangs erwähnt hatte.
    Deswegen ist _Rundos eigentlich total unnötig
    Wenn du gleich Run verwendest dann kannst du auch per StdoutRead den Output mitlesen (Dazu ruhig mal einen Blick in die Hilfe werfen!!!)
    Das Problem daran ist dass du du wahrscheinlich keine Umlaute mitbekommst

    Also ja man kann das ganze per StdOutRead lösen (wenn man die PID kennt, d.h. kein _RunDos sondern Run o.Ä.)

    Über die dir.exe ist das halt alles etwas umständlich, deswegen hatte AspirinJunkie auch zu Anfang gleich davon abgeraten.

  • ok Verstehe ich.
    ist auch nicht so das ich es nicht einsehen möchte nur Fragen bleiben halt Fragen  :)
    Danke euch


    das mit der Datenbank funktioniert ja auch soweit erstmal
    kennt ihr gute tutorials über Stout usw.
    das macht es mir immer etwas einfacher zu verstehen den die Hilfe ist jetzt gerade bei mir wieder in Englisch wegen der neuen funktionen
    das funktioniert immer dann sehr sperrlich in deutsch ist es halt doch einfacher (für mich)
    und son Tut sorgt bei miroft dafür das ich die Infos auch im Kopf behalte


    ansonsten wie gesagt DANKE an alle
    ist echt ein Luxus diese Seite

  • Ich versteh schon dass du dir verwenden willst wenn es soviel schneller ist ;)
    Es gibt zwar bestimmt Wege mit denen Autoit mithalten kann aber dir ist zunächst mal der einfachere Weg für dich

    Über einzelne Befehle gibt es keine Tutorials, weil die Hilfe eigentlich alles abdeckt.
    Nicht bös gemeint aber kann es sein, dass dir einfach noch ein gewisses Grundwissen zu Autoit fehlt?
    Wie verwendet man verschiedene Funktionen, Parameter, Rückgabewerte usw?

    Wenn du Probleme mit englisch hast dann lade dir doch die deutsche Hilfe runter ;)
    Link ist Unter Wichtige Links oder auch in meiner Signatur

  • was das lesen von funtionen usw. angeht hab ich soweit keine Problem verstehe aber was du meinst normaler weise
    lade ich mir auch immer die Deutsche Hilfe runter aber seit dem neusten Update was ja erst seit kurzen vorhanden ist, denkt die bissherige deutsche Hilfe noch nicht das ganze neue spektrum ab.

    mein kenntnissstand ist natürlich beschränkt auf die sachen mit dem ich mich bisher beschäftigt habe und das auslesen von stoudtout war halt bisher nicht benötigt.
    nehm dir die Frage aber nicht BÖSE weil sie natürlich berechtigt ist.

    ich Frage auch immer nur so genau weil ich es meinem Wissensdrang schuldig bin unbeantwortete Fragen wurmen mich.
    Daher ist eine einfache antwort nicht immer Nötig weil manchmal komm ich selbst auf de Lösung aber die kleinen stupser helfen mir doch schneller ans Ziel.  :D
    Das Kreterium meiner Beharlichkeit hier mit DIR zu arbeiten war halt die für mich sichtbar das ergebnis, sonst hätte ich schon lange die Recursive Variant umgesetzt.
    Will ja auch nicht undankbar erscheinen, jede Antwort kann hilfreich sei wenn sie mich zu anderen Gedankengängen anregt.