![]() |
Pfadinhalte eine Ebene aufwärts kopieren
Ich habe beispielsweise Dateien im Pfad
c:\temp\alt und möchte diese eine Ebene höher (In dem Falle nach c:\temp\) verschieben. Mit
Delphi-Quellcode:
bekomme ich das irgendwie nicht hin.
fDir := 'C:\temp\alt';
fDirDst := fDir + '..\..'; TDirectory.Move(fDir, fDirDst) Es kommt immer die Meldung, dass das Verzeichnis schon existiert. Da aber die Ursprungspfade nicht immer gleich sind, müsste alles relativ gehalten sein. Was mache ich falsch? |
AW: Pfadinhalte eine Ebene aufwärts kopieren
Also zum einen fehlt da bei
Delphi-Quellcode:
doch zumindest mal ein Backslash, denn als Ergebnis bekämst du ja so ein
fDirDst := fDir + '..\..';
c:\temp\alt..\.. Außerdem ist der Pfad direkt über dem c:\temp\alt ja ".." und nicht "..\.." - mit letzterem landest du schon bei c:\. Das ist mir jetzt auf die Schnelle aufgefallen... |
AW: Pfadinhalte eine Ebene aufwärts kopieren
Generell versuchst du das Verzeichnis alt im Pfad c:\temp nach c:\ zu verschieben. Der neue Pfad würde also c:\alt sein.
Ein
Delphi-Quellcode:
verschiebt das komplette Verzeichnis mit Inhalt. So wie du es beschrieben hast möchtest du aber nur den Inhalt verschieben.
TDirectory.Move
|
AW: Pfadinhalte eine Ebene aufwärts kopieren
Hast Du denn den Befehl mal händisch ausprobiert? In der Eingabeaufforderung? Macht man das heute nicht mehr?
Der Befehl dazu wäre:
Code:
Erklärung:
move C:\temp\alt ..
.. ist das übergeordnete Verzeichnis (der Vollständigkeit halber: . ist das aktuelle). Sherlock |
AW: Pfadinhalte eine Ebene aufwärts kopieren
@Sherlock
Nein, er macht aktuell
Code:
move c:\temp\alt c:\temp\alt..\..
|
AW: Pfadinhalte eine Ebene aufwärts kopieren
Klar. Aber er will ja was ich schrieb. Meine Frage ist halt darum auch gewesen, ob es ausprobiert wurde.
Vielleicht hätte ich an geeigneter Stelle noch das Wörtchen "korrekt" (mit passender Flexion) einflechten sollen... Sherlock |
AW: Pfadinhalte eine Ebene aufwärts kopieren
Zitat:
Bei
Code:
wird der Order C:\temp\alt nach C:\Foo\alt verschoben.
C:\Foo\Bar> move C:\temp\alt ..
So wie ich den TE verstanden haben möchte der von da
Code:
nach da
C:\
+- temp\ +- alt\ +- foo.txt
Code:
C:\
+- temp\ +- foo.txt Zitat:
|
AW: Pfadinhalte eine Ebene aufwärts kopieren
Kann ich nicht nachvollziehen. Unter Windows 10 verhält es sich genau so wie ich es schrieb.
move c:\temp\irgendwas .. verschiebt den Ordner irgendwas eine Ebene höher, so daß man dann ein c:\irgendwas bekommt. Sherlock |
AW: Pfadinhalte eine Ebene aufwärts kopieren
Wenn ich es richtig verstehe, soll nicht der Ordner an sich, sondern dessen Inhalt verschoben werden, so dass dieser anschließend auf derselben Ebene wie der Ursprungsordner liegt.
|
AW: Pfadinhalte eine Ebene aufwärts kopieren
@Sherlock
Dann hast du ein anderes Windows als ich. Folgende Ausgangssituation:
Code:
Ich führe aus
c:\
+- temp\ | +- alt\ | +- foo.txt +- foo\ +- bar\ <- aktuelles Verzeichnis
Code:
und erhalte das hier
C:\foo\bar>move c:\temp\alt ..
1 Verzeichnis(se) wurde(n) verschoben.
Code:
Also ich habe ein Windows 10 Pro Version 1803 Build 17134.285
c:\
+- temp\ +- foo\ +- alt\ | +- foo.txt +- bar\ <- aktuelles Verzeichnis Meinst du mein Windows ist kaputt? Sollte ich das neu installieren? Oder ist sogar die Hardware defekt? |
AW: Pfadinhalte eine Ebene aufwärts kopieren
Wir waren in verschiedenen Arbeitsverzeichnissen ;)
Ich war in Temp, Du woanders. .. bezieht sich immer auf das Arbeitsverzeichnis. Danke für die Erinnerung daran. Sherlock |
AW: Pfadinhalte eine Ebene aufwärts kopieren
Vermutlich wird das Delphi-Pendant zu
Code:
gesucht. (ja, ich weiß, das geht auch kürzer, nur um es hervorzuheben)
move C:\temp\alt\*.* C:\temp\alt\..
|
AW: Pfadinhalte eine Ebene aufwärts kopieren
Code:
Das verschiebt den Inhalt von c:\temp\alt in den übergeordneten Order in dem ich mich gerade befinde ("currentdir"\..). Also nicht nach c:\temp. Um es nach c:\temp zu verschieben müsste es so lauten:
C:\foo\bar>move c:\temp\alt ..
1 Verzeichnis(se) wurde(n) verschoben.
Code:
oder ein CD c:\temp\alt davor.
C:\foo\bar>move c:\temp\alt c:\temp\alt\..
Der korrekte Code des TE wäre also:
Code:
fDir := 'C:\temp\alt';
fDirDst := fDir + '\..'; TDirectory.Move(fDir, fDirDst); |
AW: Pfadinhalte eine Ebene aufwärts kopieren
@Rolf Frei
Wenn wir den Worten des TE die nötige Aufmerksamkeit angedeihen lassen und diesen auch Glauben schenken, dann will der den Inhalt von alt ein Verzeichnis höher verschieben. Also aus das
Code:
mach das
C:\
+- temp\ +- alt\ +- foo.txt
Code:
Du zeigst ihm, wie er von da
C:\
+- temp\ +- foo.txt
Code:
nach da kommt
C:\
+- temp\ +- alt\ +- foo.txt
Code:
Wenn du es nicht glaubst, dann einfach mal fröhlich ausprobieren.
C:\
+- temp\ +- alt\ +- foo.txt Ich kann ja auch mal den Ablauf in Worte fassen:
|
AW: Pfadinhalte eine Ebene aufwärts kopieren
Mein Code würde genau das machen, was der TE will, nur geht das nicht, weil die Windows API funktion MoveFile (gekapselt durch TDirectory.Move) als Ziel ein "nicht existierendes" Verzeichnis erwartet (siehe MSDN MoveFile Doku). Besteht das Zielverzeichnis bereits kommt der Fehler "Das angegebene Verzeichnis ist bereits vorhanden".
Das Ganze lässt sich also mit einem simplen Move Befehl nicht lösen. Da muss man alle Files einzeln kopieren und danach löschen.
Code:
procedure RFCopyDirectory(SourceDir, DestDir: string;
OverWrite: Boolean = True; const FileMask: string = '*.*'; Recursive: Boolean = True); var SR: TSearchRec; begin if (SourceDir <> '') and (DestDir <> '') then begin SourceDir := IncludeTrailingPathDelimiter(SourceDir); DestDir := IncludeTrailingPathDelimiter(DestDir); if not DirectoryExists(DestDir) then ForceDirectories(ExcludeTrailingPathDelimiter(DestDir)); if FindFirst(SourceDir + FileMask, faAnyFile, SR) = 0 then try repeat if (SR.Name <> '.') and (SR.Name <> '..') then begin if (SR.Attr and faDirectory) <> 0 then begin if Recursive then RFCopyDirectory(SourceDir + SR.Name, DestDir + SR.Name) end else begin if not CopyFile(PChar(SourceDir + SR.Name), PChar(DestDir + SR.Name), not OverWrite) then begin if GetLastError <> ERROR_FILE_EXISTS then RaiseLastOSError; end; end; end; until FindNext(SR) <> 0; finally FindClose(SR); end; end; end; function RFDelTree(Directory: string; const DelParent: Boolean = True; const FileMask: string = '*.*'; const OlderThan: TDateTime = 0.0): Boolean; var SR: TSearchRec; begin Result := True; if Directory <> '' then begin if not DirectoryExists(Directory) then Exit; Directory := IncludeTrailingPathDelimiter(Directory); if FindFirst(Directory + FileMask, faAnyFile, SR) = 0 then try repeat if (SR.Name <> '.') and (SR.Name <> '..') then begin if (OlderThan = 0.0) or ({$IF RTLVersion >= 22}SR.TimeStamp{$ELSE}FileDateToDateTime(SR.Time){$IFEND} < OlderThan) then begin if (SR.Attr and faDirectory) <> 0 then RFDelTree(Directory + SR.Name) else if not DeleteFile(Directory + SR.Name) and (Win32Platform = VER_PLATFORM_WIN32_NT) then MoveFileEx(PChar(Directory + SR.Name), nil, MOVEFILE_DELAY_UNTIL_REBOOT); end; end; until FindNext(SR) <> 0; finally FindClose(SR); end; if DelParent then begin Result := RemoveDir(Directory); if not Result and (Win32Platform = VER_PLATFORM_WIN32_NT) then Result := MoveFileEx(PChar(Directory), nil, MOVEFILE_DELAY_UNTIL_REBOOT); end else Result := True; end; end; procedure TForm1.FormCreate(Sender: TObject); var fDir, fDirDst: String; begin fDir := 'C:\temp\alt'; fDirDst := fDir + '\..'; { Kopieren aller Dateien und Unterverzeichnisse aus dem Ordner fDir ins Zielverzeichnis fDirDst } RFCopyDirectory(fDir, fDirDst); { Löschen des Quellverzeichnisses inklusive aller Unterverzeichnisse } RFDelTree(fDir); end; |
AW: Pfadinhalte eine Ebene aufwärts kopieren
Zerleg doch den Quellpfad und lass als Ziel, die letzte Ebene weg.
|
AW: Pfadinhalte eine Ebene aufwärts kopieren
Das nützt ihm nichts. Mit MoveFile (TDirectoy.Move) lässt sich ein Verzeichnis nicht in ein bereits bestehendes verschieben. Er musss da alle Dateien in den neuen Ort kopieren und danach im alten Ort löschen.
|
AW: Pfadinhalte eine Ebene aufwärts kopieren
Zitat:
|
AW: Pfadinhalte eine Ebene aufwärts kopieren
Zitat:
TDirectory.CheckMoveParameters überprüft, ob das Zielverzeichnis schon besteht. Wenn ja, wird eine Exception ausgelöst. Das ist das Problem das der TE hat. Er will das Verzeihnis/Inhalt von c:\temp\alt in das Verzeichnis c:\temp\alt\.. (also c:\temp) verschieben. c:\temp exisistiert aber bereits und löst daher die Exception aus. Im Prinzip macht TDirectoy.Move mehr oder weniger das, was ich mit meinen beiden obigen Routinen mache, also Kopieren und Löschen, aber leider geht das hier nicht auf ein bestehendes Verzeichnis, wodurch diese Funktion für die gewünschte Aufgabe nutzlos ist. Mit den von mir oben geposteten Routinen geht das problemlos. |
AW: Pfadinhalte eine Ebene aufwärts kopieren
Danke an Allen.
Ich wollte in neuen Projekten auch einmal die neuen Klassen verwenden (TFILE, TPAH, etc.). Aber anscheinend läßt sich mein Problem nur mittels der Funktionen von Rolf lösen. Danke Rolf. Ich habe verschiedene Ansätze von euch probiert, aber immer kommt die Meldung, dass ein Pfad schon vorhanden sei. Ist er ja auch. Aber warum sollte man nicht alle Verzeichnisse und Dateien eine Ebene aufwärts verschieben können. Möglicherweise noch ein Denkfehler von Emba oder MS. |
AW: Pfadinhalte eine Ebene aufwärts kopieren
Für den übergeordneten Ordner sollte doch ein Rename (statt Kopieren+Löschen) reichen, für den verbleibenden Rest dann Rolfs Prozeduren, oder?
|
AW: Pfadinhalte eine Ebene aufwärts kopieren
Delphi-Quellcode:
Versuche das mal.
function MoveDir(SrcDir, DstDir: string): Boolean;
var FOS: TSHFileOpStruct; begin ZeroMemory(@FOS, SizeOf(FOS)); with FOS do begin wFunc := FO_MOVE; // FO_COPY; fFlags := FOF_ALLOWUNDO or FOF_SIMPLEPROGRESS; pFrom := PChar(IncludeTrailingPathDelimiter(SrcDir) + '*.*'#0); pTo := PChar(DstDir + #0); end; Result := (SHFileOperation(FOS) = 0); end; |
AW: Pfadinhalte eine Ebene aufwärts kopieren
Danke, aber ich hatte das Problem noch nicht. War nur eine theoretische Überlegung von mir, da Umbenennen bei großen Dateien platten-/SSDschonender ist (und vermutlich auch schneller). :wink:
|
AW: Pfadinhalte eine Ebene aufwärts kopieren
Zitat:
Also die Variante die ich zeigte ist dieselbe die Windows einsetzt. Um auf Dich einzugehen, Ja ein "Move/Bewegen" ist schonender und schneller wenns das gleiche Laufwerk/Partition betrifft, ansonsten ist es egal. |
AW: Pfadinhalte eine Ebene aufwärts kopieren
Zitat:
@old7 Er möchte den übergeordneten Order nicht "löschen/umbennen" sondern nur den Inhalt des Untervezeichnisses in den bestehenden Überorder verschieben. Der Inhalt im übergeordneten Order soll dabei nicht verändert werden, also alles was schon besteht soll auch nach dem Move noch vorhanden sein. Zumindest habe ich das so verstanden. |
AW: Pfadinhalte eine Ebene aufwärts kopieren
Ich dachte, es ginge ihm erst mal darum den übergeordneten Ordner raus zu bekommen. Wie er dann seine Dateien dahin bekommt, wäre dann ein anderes Problem. Man könnte dann ja auch mit einem Zwischenschritt über einen temporären Ordner gehen. Liegt der in der selben Partition wird ja eh nur der Eintrag im FAT geändert und sie werden nicht physisch verschoben. Was dann auch recht schnell sein sollte.
|
AW: Pfadinhalte eine Ebene aufwärts kopieren
@Rolf
Um die Datei C:\ueber\unter\riesig.mp4 nach C:\ueber\riesig.mp4 zu verschieben, sollte ein Umbenennen der Datei riesig.mp4 reichen, falls sie noch nicht in C:\ueber vorhanden ist, das meinte ich. Das hat nichts mit dem "löschen/umbenennen" des übergeordneten Ordners zu tun, da habe ich den TE schon richtig verstanden, siehe Luckie, der übergeordnete Ordner liegt ja immer in der selben Partition, also wird nur der Eintrag in der FAT umbenannt, falls möglich. In diesem Fall kann man sich das Kopieren+Löschen von riesig.mp4 sparen. Da hast du mein "umbenennen" wohl falsch verstanden ;-) |
AW: Pfadinhalte eine Ebene aufwärts kopieren
ungefähr sowas?
Delphi-Quellcode:
In kurz (ohne Fehlerbehandlung ...):
sAlt := 'c:\temp\alt\irgendeine.mp3';
sWegdamit := '\alt\'; sNeu := AnsiReplaceText(sAlt,sWegDamit,'\'); if not SysUtils.RenameFile(sAlt,sNeu) then ShowMessage(Format('Fehler beim Umbenennen: %s',[sAlt,sNeu]));
Delphi-Quellcode:
SysUtils.RenameFile(sDateiname,AnsiReplaceText(sDateiname,'\alt\','\'));
|
AW: Pfadinhalte eine Ebene aufwärts kopieren
Jupp, und auf die Idee mit AnsiReplaceText für den Ü-Ordner wäre ich nicht gekommen (hätte die Backslashes von hinten geparst) :thumb:
|
AW: Pfadinhalte eine Ebene aufwärts kopieren
Danke euch allen.
Ich hätte nie gedacht, dass es so viele verschiedene Ansätze gibt. Mein eigentliches Problem ist, dass ich delphizip verwende und aus größeren ZIPfiles nur einige Dateien bzw. Verzeichnisse benötige. Diese sind so eingepackt, dass die Dateien, die ich entpacken will, in einem Unterverzeichnis stehen, beim Auspacken dieser Unterpfad aber stört, so ungefähr im Zipfile unnötiger Pfad\datei(en) unnötiger Pfad\nötiger Pfad\datei(en) unnötiger Pfad\nötiger Pfad\nötiger Pfad\datei(en) ausgepackt soll dann so sein datei(en) nötiger Pfad\datei(en) nötiger Pfad\nötiger Pfad\datei(en) Ich habe bisher keine Möglichkeit im Delphizip gefunden, diesen Pfad schon beim Auspacken zu eliminieren. Von Delphizip möchte ich aber auch nicht wechseln, da ich das in verschiedenen Projekten benutze. Wenn man ein Basisverzeichnis für das Zipfile hätte, vom dem dann alles entzipt werden könnte, wäre das super. Ich hoffe, dass erklärt noch einmal allen, was ich genau machen will. |
AW: Pfadinhalte eine Ebene aufwärts kopieren
Ist jetzt nicht böse gemeint, aber warum kommt das erst jetzt?
Sherlock |
AW: Pfadinhalte eine Ebene aufwärts kopieren
Zitat:
Code:
Deswegen bist du darauf nicht gekommen, weil das mit dem
C:\temp\alt\ein\alt\dir\datei.txt
Delphi-Quellcode:
sehr fehleranfällig ist
AnsiReplaceText
|
AW: Pfadinhalte eine Ebene aufwärts kopieren
Zitat:
Aber Dein Beispiel entspricht nicht der Aufgabenstellung. Es soll nur der letzte Teil aus dem Pfad entfernt werden. ;-) Lieber eher sowas?
Delphi-Quellcode:
(ungetestet hingedaddelt)
function GetNewFileName(sFilename : String) : String;
begin Result := ExtractFilePath(sFilename); Result := ExcludeTrailingPathDelimiter(Result); Result := ReverseString(Result); Result := Copy(Result,1,Pos(SysUtils.PathDelim,Result) - 1); Result := ReverseString(Result); Result := IncludeTrailingPathDelimiter(Result); Result := Result + ExtractFilename(sFilename); end; ... if not SysUtils.RenameFile(sFilename,GetNewFileName(sFilename)) then begin FehlermeldungMachen; end; |
AW: Pfadinhalte eine Ebene aufwärts kopieren
Ich hätte jetzt eher an so etwas gedacht
Delphi-Quellcode:
Wenn man mit den Pfadangeben herumspielen möchte, dann sollte man auch die entsprechenden Funktionen zum Herumspielen verwenden.
program Project1;
{$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, System.IOUtils; procedure MoveDirectoryContentOneUp( const ASource: string ); var srcPath, dstPath: string; srcEntry, dstEntry: string; begin srcPath := IncludeTrailingPathDelimiter( TPath.GetFullPath( ASource ) ); dstPath := IncludeTrailingPathDelimiter( ExpandFileName( TPath.Combine( srcPath, '..' ) ) ); for srcEntry in TDirectory.GetDirectories( srcPath ) do begin dstEntry := TPath.Combine( dstPath, ExtractRelativePath( srcPath, srcEntry ) ); TDirectory.Move( srcEntry, dstEntry ); end; for srcEntry in TDirectory.GetFiles( srcPath ) do begin dstEntry := TPath.Combine( dstPath, ExtractRelativePath( srcPath, srcEntry ) ); TFile.Move( srcEntry, dstEntry ); end; end; begin try MoveDirectoryContentOneUp( 'C:\tmp\alt' ); except on E: Exception do Writeln( E.ClassName, ': ', E.Message ); end; end. |
AW: Pfadinhalte eine Ebene aufwärts kopieren
Zitat:
Gruß K-H |
AW: Pfadinhalte eine Ebene aufwärts kopieren
@Schokohase:
Zitat:
Delphi CE ist mir noch zu unübersichtlich. |
AW: Pfadinhalte eine Ebene aufwärts kopieren
Zitat:
|
AW: Pfadinhalte eine Ebene aufwärts kopieren
Funktioniert mein Vorschlag für Dich nicht? Der bewegt Inhalt plus Unterordner in ein neues Root-Dir.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:24 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz