Zu langsames Programm zum doppelte Dateien prüfen

Übersicht BlitzBasic Beginners-Corner

Neue Antwort erstellen

etlam

Betreff: Zu langsames Programm zum doppelte Dateien prüfen

BeitragSa, Jul 01, 2006 11:43
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragSa, Jul 01, 2006 11:53
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragSa, Jul 01, 2006 12:04
Antworten mit Zitat
Benutzer-Profile anzeigen
Es werden natürlich auch Unterordner durchsucht, sonst hätte das Programm ja keinen Sinn.

etlam

BeitragSo, Jul 02, 2006 10:39
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragSo, Jul 02, 2006 10:57
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragSo, Jul 02, 2006 12:43
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragSo, Jul 02, 2006 13:34
Antworten mit Zitat
Benutzer-Profile anzeigen
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.

Neue Antwort erstellen


Übersicht BlitzBasic Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group