Daten Synchronisieren

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
Joel
Beiträge: 851
Registriert: 21.04.2006 19:22

Daten Synchronisieren

Beitrag von Joel »

Hi,

Ich habe ein Programm geschrieben, dass Daten Synchronisieren soll. Auf 2 PCs die jeweils über Network miteinander verbunden sind werden von einem PC die Daten auf den anderen Synchronisiert.

Ich Synchronisiere einmal am Tag und an jedem Tag kommt jeweils ein Ordner hinzu mit ca. 100 MB an Daten. Leider dauert die Synchronisation 5 Min. Das Manuelle kopieren des Ordners geht also viel schneller.

1. Gibt es vielleicht Tuning Möglichkeiten?

Code: Alles auswählen

Global Source$
Global Destination$
Global prozent
Global Size_Kill
Global Taste 
Global Fehler

Size_Kill = 0
Fehler = 1
Taste = 1
OpenFile(1, "config.txt")
Source$ = ReadString(1)
Destination$ = ReadString(1)
CloseFile(1)
;Source$ = "\\JOEL-PC\Users\Joel\Desktop\Audi"
;Destination$ = "\\Alter-PC\Desktop\Auda-Test"


Enumeration
  #Main
  #Button_Start
  #ProgressBar_0
  #ProgressBar_2
  #ProgressBar_3
  #Editor_0
  #Text_Status
  #Button_Beenden
EndEnumeration

Procedure.q GetDirectorySize(path$,pattern$ = "*.*") 
  If Right(path$,1)<>"\":path$+"\":EndIf 
  DirID = ExamineDirectory(#PB_Any,path$,pattern$) 
    If DirID 
    While NextDirectoryEntry(DirID) 
      If DirectoryEntryType(DirID) = #PB_DirectoryEntry_Directory 
        If DirectoryEntryName(DirID)<>"." And DirectoryEntryName(DirID)<>".." 
          TotalSize.q + GetDirectorySize(path$+DirectoryEntryName(DirID)+"\",pattern$) 
        EndIf 
      EndIf 
      If DirectoryEntryType(DirID) = #PB_DirectoryEntry_File 
        TotalSize + DirectoryEntrySize(DirID) 
      EndIf 
    Wend 
    FinishDirectory(DirID) 
  EndIf 
  ProcedureReturn TotalSize.q 
EndProcedure

Procedure Key() 
   For n=0 To 255 
      If GetAsyncKeyState_(n) 
         ProcedureReturn n 
      EndIf 
   Next 
EndProcedure


Procedure Backup(Source.s, Dest.s) 
  Protected Dir.l, entry.s, i.l, max.l 
  
  ;Wenn das Quellverzeichnis nicht existiert 
  If FileSize(Source) = -1 
     AddGadgetItem(#Editor_0, 0, "Quell-Verzeichnis existiert nicht: '" + Source + "'"  , 0, 0)
    ProcedureReturn #False 
  EndIf 
  
  ;Wenn das Zielverzeichnis noch nicht existiert, lege es an 
  If FileSize(Dest) = -1 
    i = 1 
    entry = StringField(Dest, i, "\") 
    max = CountString(Dest, "\") + 1 
    While i <= max 
      If FileSize(entry) = -1 
        If CreateDirectory(entry) = 0
        AddGadgetItem(#Editor_0, 0, "Kann Verzeichnis nicht erstellen oder Quell bzw. Ziel PC ist nicht erreichbar!"  , 0, 0)
          ProcedureReturn #False 
        EndIf 
      EndIf 
      i + 1 
      entry + "\" + StringField(Dest, i, "\") 
    Wend 
  EndIf 
  
  If Right(Source, 1) <> "\" : Source + "\" : EndIf 
  If Right(Dest, 1) <> "\" : Dest + "\" : EndIf 
  
  Dir = ExamineDirectory(#PB_Any, Source, "") 
  If Dir 
    ;alle Dateien und Verzeichnisse durchgehen 
    While NextDirectoryEntry(Dir) 
      entry = DirectoryEntryName(Dir) 
      
      If entry <> ".." And entry <> "." 
        Select DirectoryEntryType(Dir) 
          ;Wenn es ein Verzeichnis ist 
          Case #PB_DirectoryEntry_Directory 
            ;Wenn das Verzeichnis im Ziel noch nicht existiert -> anlegen und rekursiv weitermachen 
            If FileSize(Dest + entry) = -1 
              If CreateDirectory(Dest + entry) 
                Backup(Source + entry + "\", Dest + entry + "\") 
              Else 
              AddGadgetItem(#Editor_0, 0, "Verzeichnis konnte nicht erstellt werden: '" + Dest + entry + "'" , 0, 0) 
              EndIf 
            ;Ansonsten einfach rekursiv weitermachen 
            Else 
              Backup(Source + entry + "\", Dest + entry + "\") 
            EndIf 
            
          Case #PB_DirectoryEntry_File 
            ;Wenn die Datei im Ziel noch nicht existiert -> kopieren 
            If FileSize(Dest + entry) = -1 
              If Not CopyFile(Source + entry, Dest + entry) 
              AddGadgetItem(#Editor_0, 0, "Datei konnte nicht kopiert werden: '" + Source + entry + "' nach '" + Dest + entry + "'"  , 0, 0) 
              EndIf 
            ;Wenn sie schon existiert -> überprüfen, ob das Änderungsdatum neuer ist als das der Datei im Ziel 
            Else 
              ;Wenn die Datei neuer ist -> alte löschen und neue kopieren 
              If DirectoryEntryDate(Dir, #PB_Date_Modified) > GetFileDate(Dest + entry, #PB_Date_Modified) 
                If Not DeleteFile(Dest + entry) 
                  AddGadgetItem(#Editor_0, 0, "Datei konnte nicht gelöscht werden: '" + Dest + entry + "'" , 0, 0) 
                Else 
                  If Not CopyFile(Source + entry, Dest + entry) 
                    AddGadgetItem(#Editor_0, 0, "Datei konnte nicht kopiert werden: '" + Source + entry + "' nach '" + Dest + entry + "'" , 0, 0) 
                  EndIf 
                EndIf 
              EndIf 
            EndIf 
        EndSelect 
      EndIf 
    Wend 
    FinishDirectory(Dir) 
    ProcedureReturn #True 
  EndIf 
  
  ProcedureReturn #False 
EndProcedure 

Procedure Size(ee.l)
maxsize = GetDirectorySize(Source$, "*.*") 
einprozent = maxsize/100

Repeat 
Delay(1000)
size = GetDirectorySize(Destination$, "*.*") 
prozent = size/einprozent
SetGadgetState(#ProgressBar_0, prozent)
Until Size_Kill = 1

EndProcedure 

Procedure Ubertrager(d.l)
Size_Thread = CreateThread(@Size(), 33)

AddGadgetItem(#Editor_0, -1, "Übertragungprozess gestartet." , 0, 0)
If Backup(Source$, Destination$)
AddGadgetItem(#Editor_0, -1, "Prozess abgeschlossen." , 0, 0)
AddGadgetItem(#Editor_0, -1, "Programm wird automatisch beendet." , 0, 0)
Else 
AddGadgetItem(#Editor_0, 0, "Es ist ein Fehler aufgetreten. Das Programm wird nicht automatisch beendet." , 0, 0)
Fehler = 1
EndIf 
Size_Kill = 1

KillThread(Size_Thread)

If Fehler = 1
For w = 1 To 7
SetGadgetText(#Button_Beenden, "Beenden ("+Str(8-w)+" Sekunden")
Delay(1000)
Next 
End 
EndIf 
EndProcedure 


  If OpenWindow(#Main, 335, 3, 219, 409, "Audioübertrager",  #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget | #PB_Window_TitleBar )
      ButtonGadget(#Button_Start, 10, 10, 200, 40, "Vorgang Starten (Enter)")
      ProgressBarGadget(#ProgressBar_0, 10, 60, 200, 40, 0, 100)
      ;ProgressBarGadget(#ProgressBar_2, 10, 130, 200, 40, 0, 100)
      ;ProgressBarGadget(#ProgressBar_3, 10, 200, 200, 40, 0, 100)
      EditorGadget(#Editor_0, 10, 165, 200, 190)
      TextGadget(#Text_Status, 10, 125, 200, 20, "Status:", #PB_Text_Center)
      ButtonGadget(#Button_Beenden, 20, 370, 180, 30, "Beenden")
      SetGadgetColor(#Editor_0, #PB_Gadget_BackColor, RGB(0, 0, 0)) 
      SetGadgetColor(#Editor_0, #PB_Gadget_FrontColor, RGB(0, 240, 0)) 
      
      Repeat
    EventID = WaitWindowEvent()
    If Taste = 1
    If Key() = #VK_RETURN
    Ubertrager_Thread = CreateThread(@Ubertrager(), 33)
    Taste = 0
    EndIf 
    EndIf 
    If EventID = #PB_Event_Gadget
      Select EventGadget()
      
        Case #Button_Start
        
        Ubertrager_Thread = CreateThread(@Ubertrager(), 33)
        
        Case #Button_Beenden
        
        End 
        
         EndSelect

    EndIf

  Until EventID = #PB_Event_CloseWindow

EndIf

----------------------------------------------------------

PB 5.20 Beta 10 | Windows 7
walker
Beiträge: 278
Registriert: 29.08.2004 18:39
Wohnort: Bayern

Re: Daten Synchronisieren

Beitrag von walker »

... auf den 1. Blick :
Du hast 2x ein delay von 1 sekunde drin .... :freak: warum ? Das kostet bei 90 aufrufen 1,5 Minuten Zeit ... für nix

Was ich ändern würde: erst alle Verzeichnisse durchgehen und die Dateien (incl. Pfad) in einer LinkedList speichern ... diese dann auf einen Rutsch abarbeiten ... dürfte ggf. etwas schneller sein ...
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: Daten Synchronisieren

Beitrag von ts-soft »

>> 1. Gibt es vielleicht Tuning Möglichkeiten?
Delays raus (vor allem der zweite, der sogar in einer Schleife ist :freak:
Wie bereits gesagt in einem Rutsch abarbeiten, ohne Threads sondern mit einem
vernünftigen EventLoop oder Callback, dann brauchste keine Delay mehr und
die Threads machen so im Moment nichts schneller, sondern eher langsamer.

Desweiteren mal die Einrückungen korrigieren, der Code ist so nur schwer zu lesen.

Gruß
Thomas
Andesdaf
Moderator
Beiträge: 2673
Registriert: 15.06.2008 18:22
Wohnort: Dresden

Re: Daten Synchronisieren

Beitrag von Andesdaf »

trulla!?
Win11 x64 | PB 6.20
Benutzeravatar
TomS
Beiträge: 1508
Registriert: 23.12.2005 12:41
Wohnort: München

Re: Daten Synchronisieren

Beitrag von TomS »

Andesdaf hat geschrieben:trulla!?
Ja. Ziemlich irritierend :shock: :wink:
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Re: Daten Synchronisieren

Beitrag von Kaeru Gaman »

der code ist insgesamt ziemlich unübersichtlich und schwierig einzuschätzen.
das zweite Delay ist nur für den CountDown, sollte also keinen weiteren Einfluß haben.
das erste ist auch nur in der Anzeige des Fortschritts und in einem extra thread.
beides sollte sich also nicht wirklich auf den kopiervorgang auswirken, aber unglücklich ist es trotzdem.
wahrscheinlich sollte man einen völlig anderen Ansatz wählen.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Antworten