Probleme mit CopyFile unter Borland Builder 6



  • Hallo Leute,

    habe hier ein kleines Programm geschrieben, das ein Verzeichnis nach veränderten Dateien durchsucht und diese dann in ein anderes Verzeichnis kopiert.
    Das Programm funktioniert auch so weit ganz gut, leider stürzt es immer ab, wenn die zu kopierende Datenmenge größer als ca. 500 MB beträgt.
    Ich gehe mal davon aus, dass das mit der Routine CopyFile zusammenhängt, kann aber auch sein, dass ich irgendwo vergessen habe, Speicher wieder frei zu machen???
    Bin noch nicht so versiert in der Programmierung - speziell C++, daher ist das Programm auch nicht so sauber geschrieben - ich bitte dies zu verzeihen.
    Man könnte sicherlich noch einiges zusammenfassen usw. und die Portabilität ist hier sicherlich auch nicht gegeben, aber das sehe ich ersteinmal zweitrangig.

    So hier der Quelltext:
    Wäre super, wenn mir einer von euch weiterhelfen könnte!

    #include <vcl.h>
    #pragma hdrstop
    
    #include "Unit1.h"
    #include "Unit2.h"
    #include "Unit3.h"
    #include "Unit4.h"
    //#include <sys\stat.h>
    #include <time.h>
    #include <dir.h>
    #include <Filectrl.hpp>
    //#include <winnt.h>
    //#include <io.h>
    #include <stdio.h>
    #include <IniFiles.hpp>
    //#include <system.hpp>
    
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    Tmain_form *main_form;
    int countfile = 0;
    int success = 0;
    //---------------------------------------------------------------------------
    __fastcall Tmain_form::Tmain_form(TComponent* Owner)
            : TForm(Owner)
    {
             AnsiString install_pfad = GetCurrentDir();
             //main_form->Edit1->Text = install_pfad+"//conf.ini";
    
      if (FileExists(install_pfad+"//conf.ini"))
      {
          main_form->Edit2->Text = "ja";
      }
      else
          {
           main_form->Edit2->Text = "nein";
          }
    
    }
    //---------------------------------------------------------------------------
    void __fastcall Tmain_form::main_menue_beendenClick(TObject *Sender)
    {
    Close();
    }
    //---------------------------------------------------------------------------
    void SearchSubdirsProgress(const AnsiString Pfad, const AnsiString verz, const AnsiString Mask)
    {
    WIN32_FIND_DATA FindFileData;
    char FileName[MAX_PATH];
    strcpy(FileName,(Pfad+Mask).c_str());
    HANDLE h=FindFirstFile(
    FileName, // Zeiger auf den Dateinamen
    &FindFileData); // Zeiger auf struct
    if (h!=INVALID_HANDLE_VALUE)
     {
      int found=1;
      while (found)
      {
       //verz = (Pfad.Delete(1,3)).c_str();
       //verz = verz.Insert("d:\\",1).c_str();
       if ((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)!=0)
          { // Unterverzeichnis
          if (strcmp(FindFileData.cFileName,".")==0); // "." ignorieren
          else if (strcmp(FindFileData.cFileName,"..")==0); // ".." ignorieren
          else // Verzeichnis, rekursiv durchsuchen
             {
               if (!DirectoryExists(verz+FindFileData.cFileName))
                 { 
    	       CreateDir(verz+FindFileData.cFileName);
    	     }
               SearchSubdirsProgress(Pfad+FindFileData.cFileName+"\\",verz+FindFileData.cFileName+"\\",Mask);
             }
          }
       else
          {
            TSearchRec SearchRecHilf;
            if (!FileExists(verz+FindFileData.cFileName))
              {
                countfile++;
              }
            else
              {
                AnsiString file = verz+FindFileData.cFileName;
                FindFirst(file, faAnyFile, SearchRecHilf);
                if (FindFileData.ftLastWriteTime.dwLowDateTime > SearchRecHilf.FindData.ftLastWriteTime.dwLowDateTime)
                   {
                    countfile++;
                   }
              }
            FindClose(SearchRecHilf);
          }
       found=FindNextFile(h,&FindFileData);
      }
      FindClose(h);
     }
    };
    //---------------------------------------------------------------------------
    void SearchSubdirs(const AnsiString Pfad, const AnsiString verz, const AnsiString Mask)
    {
    WIN32_FIND_DATA FindFileData;
    char FileName[MAX_PATH];
    strcpy(FileName,(Pfad+Mask).c_str());
    HANDLE h=FindFirstFile(
    FileName, // Zeiger auf den Dateinamen
    &FindFileData); // Zeiger auf struct
    if (h!=INVALID_HANDLE_VALUE)
      {
        int found=1;
        while (found)
            {
              free(FileName); // nachträglich hinzugefügt
              //verz = (Pfad.Delete(1,3)).c_str();
              //verz = verz.Insert("d:\\",1).c_str();
              if ((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)!=0)
                 { // Unterverzeichnis
                   if (strcmp(FindFileData.cFileName,".")==0); // "." ignorieren
                   else if (strcmp(FindFileData.cFileName,"..")==0); // ".." ignorieren
                   else // Verzeichnis, rekursiv durchsuchen
                       {
                         if (!DirectoryExists(verz+FindFileData.cFileName))
                            {
                              CreateDir(verz+FindFileData.cFileName);
                            }
                         SearchSubdirs(Pfad+FindFileData.cFileName+"\\",verz+FindFileData.cFileName+"\\",Mask);
                       }
                 }
              else
                 {
                   TSearchRec SearchRecHilf;
                   if (!FileExists(verz+FindFileData.cFileName))
                      {
                        CopyFile((Pfad+FindFileData.cFileName).c_str(),(verz+FindFileData.cFileName).c_str(),true);
                        list_form->memo_liste->Lines->Add((Pfad+FindFileData.cFileName).c_str());
                        main_form->pgb_fortschritt->StepBy(1);
                      }
                   else
                      {
                        AnsiString file = verz+FindFileData.cFileName;
                        FindFirst(file, faAnyFile, SearchRecHilf);
                        if (FindFileData.ftLastWriteTime.dwLowDateTime > SearchRecHilf.FindData.ftLastWriteTime.dwLowDateTime)
                           {
                             DeleteFile((verz+SearchRecHilf.Name).c_str());
                             CopyFile((Pfad+FindFileData.cFileName).c_str(),(verz+FindFileData.cFileName).c_str(),true);
                             list_form->memo_liste->Lines->Add((Pfad+FindFileData.cFileName).c_str());
                             main_form->pgb_fortschritt->StepBy(1);
                           }
                      }
                   FindClose(SearchRecHilf);
                 }
              found=FindNextFile(h,&FindFileData);
            }
        FindClose(h);
      }
    };
    //---------------------------------------------------------------------------
    void checkdata (const AnsiString maske, const AnsiString pfad_verzeichnis, const AnsiString verz_ziel, int outlback)
    {
             if (main_form->Edit2->Text == "nein")
                {
                 Application->MessageBox("Konfigurationsdatei ist noch nicht vorhanden - bitte erstellen","Fehler" , MB_OK);
                 options_form->ShowModal();
                 main_form->Edit2->Text = "ja";
    
                }
             else
                {
                 if (outlback == 0)
                 {
                  //const AnsiString pfad_verzeichnis = options_form->ed_datei_quell_pfad->Text.c_str();
                  SearchSubdirsProgress(pfad_verzeichnis,verz_ziel, maske);
                  main_form->pgb_fortschritt->Max = countfile;
                  //main_form->Edit1->Text = countfile;
                  SearchSubdirs(pfad_verzeichnis,verz_ziel, maske);
                 }
                 else
                 {
                  SearchSubdirsProgress(pfad_verzeichnis,verz_ziel, maske);
                  main_form->pgb_fortschritt->Max = countfile;
                  //main_form->Edit1->Text = (countfile/2);
                  SearchSubdirs(pfad_verzeichnis,verz_ziel, maske);
                 }
                }
    }
    
    //---------------------------------------------------------------------------
    
    void __fastcall Tmain_form::bt_sichernClick(TObject *Sender)
    {
    
     if (cb_dateien->Checked && cb_outlook->Checked)
           {
             const AnsiString outl = options_form->memo_config->Lines->Strings[0];
             const AnsiString v_ziel = options_form->memo_config->Lines->Strings[2];
             const AnsiString v_quell = options_form->memo_config->Lines->Strings[1];
             if (!DirectoryExists(options_form->memo_config->Lines->Strings[0]) && !DirectoryExists(options_form->memo_config->Lines->Strings[1]))
                  {
                   Application->MessageBox("Verzeichnisse sind nicht vorhanden - bitte konfigurieren","Fehler" , MB_OK);
                  }
             else
                  {
                   checkdata("*", outl, v_ziel, 1);
                   checkdata("*", v_quell, v_ziel, 1);
                  }
           }
     else
           {
            if (cb_outlook->Checked)
            {
             const AnsiString outl = options_form->memo_config->Lines->Strings[0];
             const AnsiString v_ziel = options_form->memo_config->Lines->Strings[2];
             if (!DirectoryExists(options_form->memo_config->Lines->Strings[0]) && !DirectoryExists(options_form->memo_config->Lines->Strings[2]))
                  {
                   Application->MessageBox("Verzeichnisse sind nicht vorhanden - bitte konfigurieren","Fehler" , MB_OK);
                  }
             else
                  {
                   checkdata("*", outl, v_ziel, 0);
                  }
            }
            else
             {
              if (cb_dateien->Checked)
              {
                const AnsiString v_quell = options_form->memo_config->Lines->Strings[1];
                const AnsiString v_ziel = options_form->memo_config->Lines->Strings[2];
                if (!DirectoryExists(options_form->memo_config->Lines->Strings[1]) && !DirectoryExists(options_form->memo_config->Lines->Strings[2]))
                  {
                   Application->MessageBox("Verzeichnisse sind nicht vorhanden - bitte konfigurieren","Fehler" , MB_OK);
                  }
                else
                  {
                   checkdata("*", v_quell, v_ziel, 0);
                  }
              }
              else
              {
                Application->MessageBox("Bitte machen Sie erst eine Auswahl","Fehler" , MB_OK);
              }
             }
           }
    if (success > 0 || countfile > 0)
    {
    Application->MessageBox("Sicherung erfolgreich","Juhu" , MB_OK);
    countfile = 0;
    }
    else
    {Application->MessageBox("Nichts gesichert","Sorry" , MB_OK);}
    }
    //---------------------------------------------------------------------------
    
    void __fastcall Tmain_form::bt_listeClick(TObject *Sender)
    {
    list_form->ShowModal();
    }
    //---------------------------------------------------------------------------
    
    void __fastcall Tmain_form::main_menue_infoClick(TObject *Sender)
    {
      AboutBox->ShowModal();      
    }
    //---------------------------------------------------------------------------
    
    void __fastcall Tmain_form::main_menu_allgemeinClick(TObject *Sender)
    {
      options_form->ShowModal();
    }
    //---------------------------------------------------------------------------
    

    PS: bin bisher immer mit der suchen-Funktion weiter gekommen, aber jetzt wusste ich einfach nicht mehr weiter!



  • Wenn du das mal vernünftig einrückst, schaut es sich vielleicht auch jemand an.



  • Hast ja recht.
    Eigentlich sollte man das ja auch von Anfang an machen!!

    Ich hoffe jetzt ist es besser?!?!



  • char FileName[MAX_PATH];
    strcpy(FileName,(Pfad+Mask).c_str());
    .
    .
    .
    free(FileName); // nachträglich hinzugefügt

    Was soll das ???
    Du gibst NICHT dynamisch belegten Speicher frei?

    Sollte doch nen Fehler verursachen.



  • free(Filename);
    habe ich nachträglich hinzugefügt. Ohne stürzt das Programm auch ab.



  • An welcher Stelle, mit welcher Fehlermeldung?



  • Na ja, es ist kein Absturz im eigentlichen Sinne. Das Programm läuft zwar weiter und erledigt den Job auch. Jedoch wird im Taskmanager der Status "Keine Rückmeldung" angezeigt, und ich kann das Programm nur abschießen.
    Vielleicht habe ich das oben ein wenig falsch formuliert. Der Debugger zeigt keine Fehlermeldung an und das Programm läuft weiter.
    Mich stört nur, dass das Programm während der Such- und Kopierphase nicht reagiert.
    Das ist auch der Grund warum ich nicht wirklich weiter komme. Habe auch schon versucht an der Debugger-Optionen ein wenig zu schrauben bzw. mir die Threads und alles andere, was man sich unter "Ansicht" anzeigen lassen kann, angesehen.
    Doch leider werde ich daraus nicht wirklich schlau.



  • Pack ein Application->ProcessMessages(); in die Schleifen.
    Wenn das nicht reicht, z.B. wegen einzelner sehr grosser Dateien, dann musst du die Kopiererei in eigene Threads auslagern (siehe z.B. TThread).



  • Vielen Dank, werde das mal versuchen!



  • Application->ProcessMessages();
    brachte eigentlich schon den gewünschten erfolg.
    Werde aber auch mal das mit den Threds ausprobieren.

    Ach und danke für die schnelle Hilfe!



  • tha_dude schrieb:

    Na ja, es ist kein Absturz im eigentlichen Sinne. Das Programm läuft zwar weiter und erledigt den Job auch. Jedoch wird im Taskmanager der Status "Keine Rückmeldung" angezeigt, und ich kann das Programm nur abschießen.

    Der Task-Manager kann auch nicht wirklich überprüfen, ob ein Programm noch arbeitet - der schickt nur regelmäßig Messages ala "bist du noch da?" und setzt die Anzeige auf inaktiv, wenn das Programm nicht antwortet. (und da du in deiner Schleife die Nachrichten nicht abfragst, reagiert das Programm inzwischen nicht auf diese Anfragen)


Anmelden zum Antworten