Verzeichnisse kopieren

Für Fragen von Einsteigern und Programmieranfängern...
Aliobaba
Lazarusforum e. V.
Beiträge: 412
Registriert: Di 1. Mai 2012, 09:11

Verzeichnisse kopieren

Beitrag von Aliobaba »

Hallo,

Ist es eigentlich möglich, mit Lazarus ein Verzeichnis mit Unterverzeichnissen auf der Festplatte zu kopieren, ohne externe Programme (TProcess, DOS) dazu aufzurufen.
Mit der Suchfunktion hier ("Verzeichnis kopieren") habe ich es natürlich schon versucht, aber nichts gefunden. Auch habe ich versucht, es mit meinen bescheidenen Kenntnissen selber zu programmieren ("FindAllFiles" usw.).
Aber dabei glaube ich, dass ich wahrscheinlich das Rad (schlecht) neu erfinde.
Wahrscheinlich ist diese Frage hier allzu trivial; aber ich finde keine gute Lösung.

Gruß
Alfons
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Benutzeravatar
theo
Beiträge: 8643
Registriert: Mo 11. Sep 2006, 19:01

Re: Verzeichnisse kopieren

Beitrag von theo »


Warf
Beiträge: 1562
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: MacOS | Win 10 | Linux
CPU-Target: x86_64
Wohnort: Aachen

Re: Verzeichnisse kopieren

Beitrag von Warf »

Ich hab mal eine pathlib unit geschrieben mit denen man pfade managen kann. Kopieren von Dateien und Verzeichnissen ist eine der funktionalitäten die sie bereitstellt: Link
Beispiel:

Code: Alles auswählen

TPath('test').Copy('newtest');

Benutzeravatar
Winni
Beiträge: 721
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.0.12, fpc 3.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Verzeichnisse kopieren

Beitrag von Winni »

Hi!

Das muss man nicht selbst machen.
Das ist schon längst alles vorhanden.

In der Unit FileUtil:

Code: Alles auswählen

function CopyDirTree(const SourceDir, TargetDir: string; Flags: TCopyFileFlags=[]): Boolean;

Die TCopyFileFlags stehen zm Source gleich darüber.

Winni

Warf
Beiträge: 1562
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: MacOS | Win 10 | Linux
CPU-Target: x86_64
Wohnort: Aachen

Re: Verzeichnisse kopieren

Beitrag von Warf »

Die Unit FileUtil benötigt allerdings die LCL und damit Lazarus. Wenn man das eh benutzt ist das eine super Möglichkeit, einer der Gründe warum meine pathlib das allerdings selbst implementiert ist allerdings genau der Grund das die meisten meiner Programme mittlerweile Konsolenprogramme sind die mittels CI/CD gebaut und deployed werden, Lazarus als Buildsystem zu verwenden das unfassbar verkompliziert.

Benutzeravatar
Winni
Beiträge: 721
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.0.12, fpc 3.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Verzeichnisse kopieren

Beitrag von Winni »

Warf hat geschrieben:
Fr 12. Mär 2021, 19:25
Die Unit FileUtil benötigt allerdings die LCL und damit Lazarus.
....
, Lazarus als Buildsystem zu verwenden das unfassbar verkompliziert.
Er sagt, er möchte wissen, wie das in Lazarus geht.
Lesen hilft.

Warf
Beiträge: 1562
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: MacOS | Win 10 | Linux
CPU-Target: x86_64
Wohnort: Aachen

Re: Verzeichnisse kopieren

Beitrag von Warf »

Viele leute benutzen Lazarus als ausdruck für fpc Object Pascal, vor allem da man ja auch Lazarus für Konsolenanwendungen benutzt, auch wenn es am Ende nicht Teil des Buildsystems ist. Ich entwickel ja auch in Lazarus, benutz die IDE und das Debugger interface, hab nur die anforderung das es am ende auch ohne Lazarus laufen soll.

Mal ganz davon abgesehen das es generell auch Leute gibt die ihren dependency Fußabdruck möglichst gering halten wollen, und die LCL zu includen für eine funktion ist schon ein bisschen overkill

Benutzeravatar
Winni
Beiträge: 721
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.0.12, fpc 3.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Verzeichnisse kopieren

Beitrag von Winni »

Warf hat geschrieben:
Fr 12. Mär 2021, 19:48
Viele leute benutzen Lazarus als ausdruck für fpc Object Pascal, vor allem da man ja auch Lazarus für Konsolenanwendungen benutzt, auch wenn es am Ende nicht Teil des Buildsystems ist. Ich entwickel ja auch in Lazarus, benutz die IDE und das Debugger interface, hab nur die anforderung das es am ende auch ohne Lazarus laufen soll.

Mal ganz davon abgesehen das es generell auch Leute gibt die ihren dependency Fußabdruck möglichst gering halten wollen, und die LCL zu includen für eine funktion ist schon ein bisschen overkill

Wo hat er danach gefragt?
Kopfschüttel.

Warf
Beiträge: 1562
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: MacOS | Win 10 | Linux
CPU-Target: x86_64
Wohnort: Aachen

Re: Verzeichnisse kopieren

Beitrag von Warf »

Hat er nicht, aber er hat auch nicht gesagt das es unbedingt eine LCL spezifische Lösung sein muss.

Ich habe meine antwort gegeben da das eine Lösung für sein problem ist. Das heißt ja nicht das ich der Meinung bin das es keine anderen Lösungen gibt, oder das das die beste Lösung ist. Im Gegenteil, wenn man bereits die LCL benutzt sollte man nicht für nur eine funktion eine andere Unit einbinden. Aber ich bin auch der meinung das man für eine Unit nicht unbedingt sich Lazarus komplett ans bein binden muss wenn man bis auf diese unit auch ohne klar kommt.

Alles was ich gesagt habe ist das es situationen gibt in der meine Lösung besser ist als z.b. die LCL variante. Ob das auf die situation des Thread erstellers zutrifft oder nicht kann er selbst entscheiden. Nicht nur das, sondern dieses Forum ist auch öffentlich, also wenn jemand per Google oder Suchfunktion dieses Thema findet, der vielleicht nicht 100% die selben Anforderungen wie der TE hat ist es doch ganz nett wenn mehrere alternativen hier bereitgestellt werden, oder denkst du das es was schlechtes ist mehr möglichkeiten zu haben das Problem zu lösen?

Oder soll ich bevor ich eine antwort schreibe immer dich persönlich fragen ob die antwort gut genug für den TE ist bevor ich sie öffentlich mache?

Aliobaba
Lazarusforum e. V.
Beiträge: 412
Registriert: Di 1. Mai 2012, 09:11

Re: Verzeichnisse kopieren

Beitrag von Aliobaba »

Hallo,

Lieben Dank für die vielen Antworten!

Wenn ich die Funktion "ohne Flag" aufrufe, also so:
CopyDirTree( '/home/ali/A_Test1/' , '/home/ali/A_Test2/' );
oder so:
CopyDirTree( '/home/ali/A_Test1/*' , '/home/ali/A_Test2/' );
dann kompiliert das Programm ohne Fehler - - aber kopiert wird nichts.

Und nun weiß ich nicht, was man da als Flag eintragen muss.
Ich hätte mir nicht getraut, so eine wahrscheinlich dumme Frage zu stellen, aber offenbar haben/hatten das Problem andere auch:
viewtopic.php?t=10667

Hat jemand noch die Geduld, einen Beispielcode zu posten?

Grüße
Alfons
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Benutzeravatar
Winni
Beiträge: 721
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.0.12, fpc 3.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Verzeichnisse kopieren

Beitrag von Winni »

Hallo!

Das "Geheimnis" der Flags:

Code: Alles auswählen

type
  TCopyFileFlag = (
    cffOverwriteFile,
    cffCreateDestDirectory,
    cffPreserveTime
    );
  TCopyFileFlags = set of TCopyFileFlag;
* cffOverwriteFile: Überschreibt gleichnamige vorhandene Dateien
* cffCreateDestDirectory: Erzeugt das Zielverzeichnis, wenn es nicht vorhanden ist
* cffPreserveTime: Übernimmt den Zeitstempel der Quelldatei - statt "jetzt"

Ich schätze mal, das das Zielverzeichnis (A_Test2) nicht existiert.
Es muss also erzeugt werden: cffCreateDestDirectory

Dann benutze das mal so:

Code: Alles auswählen

CopyDirTree( '/home/ali/A_Test1/' , '/home/ali/A_Test2/' ,[ cffOverwriteFile,  
                                                 cffCreateDestDirectory,    cffPreserveTime ] );
Hoffe es klappt nun.

Winni

Aliobaba
Lazarusforum e. V.
Beiträge: 412
Registriert: Di 1. Mai 2012, 09:11

Re: Verzeichnisse kopieren

Beitrag von Aliobaba »

Danke, Winni,

leider klappt's nicht.
Showmessage('+');
CopyDirTree( '/home/ali/A_Test1/' , '/home/ali/A_Test2/' ,[ cffOverwriteFile, cffCreateDestDirectory, cffPreserveTime ] );
Showmessage('#');
Ich rufe den oben genannten Code auf; die beiden "Showmessage" dienen mir als Kontrolle, dass die Befehle auch wirklich durchlaufen werden.
Leider tut sich nichts; der Ordner "/home/ali/A_Test1/" ist tatsächlich auch mit diesem Pfad vorhanden. :|

Grüße
Alfons
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Aliobaba
Lazarusforum e. V.
Beiträge: 412
Registriert: Di 1. Mai 2012, 09:11

Re: Verzeichnisse kopieren

Beitrag von Aliobaba »

... kurzer Nachtrag:
Showmessage('+');
CopyDirTree( '/home/ali/A_Test1/' , '/home/ali/A_Test2/' ,[ cffOverwriteFile, cffCreateDestDirectory, cffPreserveTime ] );
if CopyFile( PChar ( '/home/ali/A_Test1/Test.txt' ) , PChar( '/home/ali/A_Test3/Test_xy.txt' ) , false ) then ;
Showmessage('#');
Der Befehl "CopyFile" funktioniert in diesem Beispiel problemlos.
Also sollten auch evtl. Probleme bei den Zugriffsrechten keine Rolle spielen.
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 4591
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Niederösterreich
Kontaktdaten:

Re: Verzeichnisse kopieren

Beitrag von af0815 »

Gibt es einen Fehler oder läuft das als Ok durch ?!

Code: Alles auswählen

  if not CopyDirTree( '/home/ali/A_Test1/' , '/home/ali/A_Test2/' ,[ cffOverwriteFile, cffCreateDestDirectory, cffPreserveTime ] ) then
    ShowMessage(SysErrorMessage(GetLastOSError));  
Bei deinem Beispiel dürfte ein Strichpunkt (=Leerbefehl) zuviel sein.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Aliobaba
Lazarusforum e. V.
Beiträge: 412
Registriert: Di 1. Mai 2012, 09:11

Re: Verzeichnisse kopieren

Beitrag von Aliobaba »

Hallo,

Mit diesem Code kommt die Fehlermeldung: "No such file or directory"
Was aber eigenartig ist, denn der Ordner "/home/ali/A_Test1/" existiert ganz eindeutig (habe den soeben geschriebenen Pfad extra von Dolphin (Linux-"Explorer") hierher kopiert.
Es war auch kein Strichpunkt zu viel; habe die Codes untereinander kopiert -> identische Befehle.

Es ist schon wirklich sehr seltsam. :|

Ich habe mir nun doch mit einem eigenen Code geholfen.
Er scheint sehr gut zu funktionieren. Ich kopiere ihn mal hierher (und nehme einfach mal "mittleidiges Lächeln" der Experten hier in Kauf. Vielleicht schaut ja mal einer über den Code)

Vielen Dank für Eure Hilfsbereitschaft!

Alfons

Procedure Verzeichnis_copy (Quellordner , Zielordner : string);
var
List_x : TStringList;
yyy : string;
n : Integer;
begin
List_x := TStringList.Create;
List_x.Clear;
List_x := FindAllFiles( Quellordner , '*' , true );
for n := 0 to ( List_x.Count - 1 ) do // bei 0 beginnen: Alle Dateieinträge
begin
yyy := StringReplace( List_x[n] , Quellordner , '' ,[rfReplaceAll]);
yyy := Zielordner + yyy;
ForceDirectories (ExtractFilePath( yyy ));
if CopyFile( PChar ( List_x[n] ) , PChar( yyy ) , false ) then ;
end;
List_x.Free;
end;
(Schade, dass die Leerzeichen zum Zeilenbeginn nicht angezeigt werden; das macht es etwas unübersichtlicher)
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Antworten