Zu langsames Programm zum doppelte Dateien prüfen
Übersicht

![]() |
etlamBetreff: Zu langsames Programm zum doppelte Dateien prüfen |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hallo,
ich habe ein kleines Programm geschrieben, in welchem man zuerst einen Ordner angibt, wie z.B. C:\x\ und das Programm dann alle Datei-Namen, die in dem Ordner sind in eine Datei schreibt, danach werden alle doppelten Namen in eine andere Datei geschrieben, geprüft ob auch der Datei-inhalt gleich ist und schliesslich werden alle doppelten Dateien mit gleichem inhalt in doppelte_dateien.txt geschrieben. Hier erstmal der Code: Code: [AUSKLAPPEN] Global count% = 0 Global dateinamen = WriteFile("dateinamen.dat") dirr$ = CurrentDir$() verzeichniss$ = Input("Verzeichnis (z.b:'C:\'):") Print ("Gewaeltes Verzeichnis: '" + verzeichniss$ + "'") Print ("Starte...") scandir(verzeichniss$) Type entry Field dat$ End Type Function scandir(verzeichnis$) dir=ReadDir(verzeichnis$) datei$=NextFile$(dir) While datei$="." Or datei$=".." datei$=NextFile$(dir) Wend While Not datei$="" If FileType(verzeichnis$+datei$)=2 Print "Ordner:" + Datei$ scandir(verzeichnis$+datei$+"\") Else Print "Datei:" + Datei$ WriteLine(dateinamen,Datei$) WriteLine(dateinamen,verzeichnis$+datei$) count=count+1 EndIf datei$=NextFile$(dir) Wend CloseDir (verzeichnis$) End Function CloseFile(dateinamen) ;;;;;;;;; Print ("Dateiverzeichnung abgeschlossen!") Print ("Es wurden " + count% + " Dateien verzeichnet.") Print ("Taste druecken zum fortfahren...") WaitKey() Print ("Suche nun doppelte...") dopubled = WriteFile("doppelt.dat") vvvvvvvvvvvvv% = 0 .x vvvvvvvvvvvvv% = vvvvvvvvvvvvv% + 1 Print ("Name " + vvvvvvvvvvvvv% + " ist dran...") dateinamen = ReadFile("dateinamen.dat") If Eof(dateinamen) Goto y filename$ = ReadLine(dateinamen) filepath$ = ReadLine(dateinamen) While Not Eof(dateinamen) newfilename$ = ReadLine(dateinamen) newfilepath$ = ReadLine(dateinamen) If filename$=newfilename$ Then CloseFile(dateinamen) WriteLine(dopubled,filepath$) WriteLine(dopubled,newfilepath$) delete_entry("dateinamen.dat",filename$) delete_entry("dateinamen.dat",filepath$) delete_entry("dateinamen.dat",newfilepath$) Goto x EndIf If Eof(dateinamen) CloseFile(dateinamen):delete_entry("dateinamen.dat",filename$):delete_entry("dateinamen.dat",filepath$):Goto x Wend .y CloseFile(dateinamen) ;;;;;;; ;delete_entry("test.txt","ich will gelöscht werden") Function delete_entry(path$,del$) file=ReadFile(path$) While Not Eof(file) tmp$=ReadLine(file) If tmp$<>del$ e.entry=New entry e\dat=tmp$ EndIf Wend CloseFile(file) file=WriteFile(path$) For e.entry=Each entry WriteLine(file,e\dat) Delete e.entry Next CloseFile(file) End Function CloseFile(dopubled) Print("Suche abgeschlossen-ueberpruefe nun file inneres...") doppelte_datei = ReadFile("doppelt.dat") ausgabe = WriteFile("DOPPELTE_DATEIEN.TXT") While Not Eof(doppelte_datei) istgleich% = 2 file_a$= ReadLine(doppelte_datei) file_b$ = ReadLine(doppelte_datei) ;Print file_a$ ;Print file_b$ If Not FileSize(file_a$) = FileSize(file_b$) Then istgleich% = 0 If Not istgleich% = 0 Then filee_a = ReadFile(file_a$) filee_b = ReadFile(file_b$) While Not Eof(filee_a) fil_a% = ReadByte(filee_a) fil_b% = ReadByte(filee_b) ;Print fil_a% ;Print fil_b% If Not fil_a% = fil_b% Then istgleich% = 0 If istgleich% = 0 Then Exit If Eof(filee_a) Then istgleich% = 1 If istgleich% = 0 Then Exit Wend If istgleich% = 1 Then WriteLine(ausgabe,file_a):WriteLine(ausgabe,file_b):Print ("A: " + file_a):Print ("B: " + file_b) CloseFile(filee_a) CloseFile(filee_b) EndIf Wend CloseFile(doppelte_datei) CloseFile(ausgabe) DeleteFile("dateinamen.dat") DeleteFile("doppelt.dat") Print "Fertig! (Fenster schliest sich nach 3 sek. selbst)" Delay 3000 End Mein Problem ist die Geschwindigkeit, bei 500 Dateien geht die Geschwindigkeit ja noch, aber bei 5000 aufwärts dauert es einfach zu lange. Fällt vielleicht jemandem ein, wie man das ganze beschleunigen könnte? Vielen Dank schon mal im varaus, etlam |
||
![]() |
Justus |
![]() Antworten mit Zitat ![]() |
---|---|---|
Es ist unmöglich, zwei Dateien mit dem selben Dateinamen in einem Ordner zu haben.
Es wäre cooler, wenn du einfach die beiden MD5-Hashes der Dateien miteinander vergleichen würdest, dann wüsstest du sofort, ob der Inhalt gleich ist oder nicht. |
||
![]() |
etlam |
![]() Antworten mit Zitat ![]() |
---|---|---|
Es werden natürlich auch Unterordner durchsucht, sonst hätte das Programm ja keinen Sinn. | ||
![]() |
etlam |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hat keiner eine Idee?
Hier noch mal der Code-Auschnitt, der so lange dauert: Code: [AUSKLAPPEN] Print ("Suche nun doppelte...") dopubled = WriteFile("doppelt.dat") x% = 0 vvvvvvvvvvvvv% = 0 .x vvvvvvvvvvvvv% = vvvvvvvvvvvvv% + 1 Print ("Name " + vvvvvvvvvvvvv% + " ist dran...") y% = 0 dateinamen = ReadFile("dateinamen.dat") While y% < x% ReadLine(dateinamen) y% = y% + 1 Wend If Eof(dateinamen) Goto y filename$ = ReadLine(dateinamen) filepath$ = ReadLine(dateinamen) While Not Eof(dateinamen) newfilename$ = ReadLine(dateinamen) newfilepath$ = ReadLine(dateinamen) If filename$=newfilename$ Then CloseFile(dateinamen) WriteLine(dopubled,filepath$) WriteLine(dopubled,newfilepath$) delete_entry("dateinamen.dat",filename$) delete_entry("dateinamen.dat",filepath$) delete_entry("dateinamen.dat",newfilepath$) Goto x EndIf If Eof(dateinamen) CloseFile(dateinamen):x% = x% + 2:Goto x Wend .y CloseFile(dateinamen) Function delete_entry(path$,del$) file=ReadFile(path$) While Not Eof(file) tmp$=ReadLine(file) If tmp$<>del$ e.entry=New entry e\dat=tmp$ EndIf Wend CloseFile(file) file=WriteFile(path$) For e.entry=Each entry WriteLine(file,e\dat) Delete e.entry Next CloseFile(file) End Function CloseFile(dopubled) Es dauert warscheinlich so lange, weil die Funktion delete_entry die ganze Datei neu einliest und wieder schreibt und weil jedesmal, wenn nach doppelten geprüft wird die ganze Datei gelesen wird. Fällt vielleicht jemandem ein, wie man das ganze beschleunigen könnte? Vielen Dank schon mal im varaus, etlam |
||
![]() |
kreisman |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hmm brauchst du die "dateinamen.dat"?Oder benutzt du die nur zum zwischenspeichern?Wenn du sie zum zwischenspeichern benutzt würd ich das nicht mit dateien machen.Den etwas auf die Festplatte zu schrieiben ist langsam.Benutz lieber den Speicher. | ||
![]() |
etlam |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich habe jetzt dateinamen.dat herausgenommen und alles über Types gemacht,
Code: [AUSKLAPPEN] Type dateien_verz Field datei$ Field verzeichnis$ End Type Global xxxx% = 0 Global dateinamen = WriteFile("dateinamen.dat") dirr$ = CurrentDir$() verzeichniss$ = Input("Verzeichnis (z.b:'C:\'):") Print ("Gewaeltes Verzeichnis: '" + verzeichniss$ + "'") Print ("Starte...") scandir(verzeichniss$) Type entry Field dat$ End Type Function scandir(verzeichnis$) dir=ReadDir(verzeichnis$) datei$=NextFile$(dir) While datei$="." Or datei$=".." datei$=NextFile$(dir) Wend While Not datei$="" If FileType(verzeichnis$+datei$)=2 Print "Ordner:" + Datei$ scandir(verzeichnis$+datei$+"\") Else Print "Datei:" + Datei$ datta.dateien_verz = New dateien_verz datta\datei$ = Datei$ datta\verzeichnis$ = verzeichnis$+datei$ xxxx% = xxxx% + 1 ;WriteLine(dateinamen,Datei$) ;WriteLine(dateinamen,verzeichnis$+datei$) count=count+1 EndIf datei$=NextFile$(dir) Wend CloseDir (verzeichnis$) End Function CloseFile(dateinamen) ;;;;;;;;; Print ("Dateiverzeichnung abgeschlossen!") Print ("Es wurden " + xxxx% + " Dateien verzeichnet.") Print ("Taste druecken zum fortfahren...") WaitKey() Print ("Suche nun doppelte...") dopubled = WriteFile("doppelt.dat") x% = 0 vvvvvvvvvvvvv% = 0 .x vvvvvvvvvvvvv% = vvvvvvvvvvvvv% + 1 Print ("Name " + vvvvvvvvvvvvv% + " ist dran...") y% = 0 ;dateinamen = ReadFile("dateinamen.dat") ;While y% < x% ; ReadLine(dateinamen) ; y% = y% + 1 ;Wend If First dateien_verz = Null Goto y xyyy.dateien_verz = First dateien_verz filename$ = xyyy\datei$;ReadLine(dateinamen) filepath$ = xyyy\verzeichnis$ ;ReadLine(dateinamen) klajsfklj% = 0 For lllaaa.dateien_verz = Each dateien_verz If klajsfklj% = 0 Then klajsfklj% = 1 Else newfilename$ = lllaaa\datei$;ReadLine(dateinamen) newfilepath$ = lllaaa\verzeichnis$;ReadLine(dateinamen) If filename$=newfilename$ Then WriteLine(dopubled,filepath$) WriteLine(dopubled,newfilepath$) Delete xyyy Delete lllaaa ;delete_entry("dateinamen.dat",filename$) ;delete_entry("dateinamen.dat",filepath$) ;delete_entry("dateinamen.dat",newfilepath$) Goto x EndIf EndIf ;If lllaaa=Null CloseFile(dateinamen):x% = x% + 2:Goto x Next Delete xyyy Delete lllaaa Goto x .y ;CloseFile(dateinamen) ;;;;;;; ;delete_entry("test.txt","ich will gelöscht werden") Function delete_entry(path$,del$) file=ReadFile(path$) While Not Eof(file) tmp$=ReadLine(file) If tmp$<>del$ e.entry=New entry e\dat=tmp$ EndIf Wend CloseFile(file) file=WriteFile(path$) For e.entry=Each entry WriteLine(file,e\dat) Delete e.entry Next CloseFile(file) End Function CloseFile(dopubled) Print("Suche abgeschlossen-ueberpruefe nun file inneres...") doppelte_datei = ReadFile("doppelt.dat") ausgabe = WriteFile("DOPPELTE_DATEIEN.TXT") While Not Eof(doppelte_datei) istgleich% = 2 file_a$= ReadLine(doppelte_datei) file_b$ = ReadLine(doppelte_datei) ;Print file_a$ ;Print file_b$ If Not FileSize(file_a$) = FileSize(file_b$) Then istgleich% = 0 If Not istgleich% = 0 Then filee_a = ReadFile(file_a$) filee_b = ReadFile(file_b$) While Not Eof(filee_a) fil_a% = ReadByte(filee_a) fil_b% = ReadByte(filee_b) ;Print fil_a% ;Print fil_b% If Not fil_a% = fil_b% Then istgleich% = 0 If istgleich% = 0 Then Exit If Eof(filee_a) Then istgleich% = 1 If istgleich% = 0 Then Exit Wend If istgleich% = 1 Then WriteLine(ausgabe,file_a):WriteLine(ausgabe,file_b):Print ("A: " + file_a):Print ("B: " + file_b) CloseFile(filee_a) CloseFile(filee_b) EndIf Wend ;Next CloseFile(doppelte_datei) CloseFile(ausgabe) DeleteFile("dateinamen.dat") DeleteFile("doppelt.dat") Print "Fertig! (Fenster schliest sich nach 3 sek. selbst)" Delay 3000 End Das Programm ist dadurch viel schneller geworden, aber trotzdem ist das Programm noch immer etwas zu langsam, wie kann ich denn sonst noch Geschwindigkeit rausholen? Vielen Dank schon mal im voraus, etlam |
||
![]() |
kreisman |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hmm als letzte möglichkeit würde mir nur einfallen anstatt den Types eine Bank zu benutzen.Allerdings ist die handhabung von Strings bei Banks ein wenig schwierig,da es keine Funktion gibt um Strings ind die Bank zu schrieben.Ich hab dir aber mal eine solche funtionen geschrieben:
Code: [AUSKLAPPEN] Function PokeString(bank,pos,wString$)
PokeByte bank,pos,Len(wString$) For i = 1 To Len(wString$) PokeByte bank,pos+i,Asc(Mid(wString$,i)) Next End Function Function PeekString$(bank,pos) length = PeekByte (bank,pos) For i = 1 To length result$=result$+Chr$(PeekByte(bank,pos+i)) Next Return result$ End Function Ich hab aber keine ahnung ob das wirklich schneller ist.Aber vorsicht die String dürfen nicht länger als 255 zeichen sein.Sonst musst bei length mit Integern arbeiten. |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group