I am creating a function that copies a folder and pastes it with another name.
Therefore, I have my "Main" folder and according to the query I make copies of the folder called like this: "Main 1", "Main 2", "Main 3"
The way I managed to solve this was through this function:
function TDMMonitor.CopyFolder(Origin, Destination : String) : Boolean;
var
aFiles : TStringDynArray;
InFile, OutFile: string;
Begin
aFiles := TDirectory.GetFiles(Origin, '*.*', TSearchOption.soAllDirectories);
for InFile in aFiles do
Begin
OutFile := TPath.Combine(Destination , TPath.GetFileName(InFile));
TFile.Copy(InFile, OutFile, True);
End;
Result := True;
End;
This works! But my problem right now is that the parent folder has subfolders that are not being copied correctly.
I leave a more visual example of the results of my function below:
"Main" folder:
- File.txt
- File1.txt
- Sub-Folder -> File3.txt
"Main 1" folder:
- File.txt
- File1.txt
- File3.txt
How can I maintain the folder structure that the Main folder follows?
CodePudding user response:
TDirectory.Copy works:
TDirectory.Copy('D:\Path\Main', 'D:\Path\Main 1');
CodePudding user response:
TDirectory.GetFiles()
returns an array of absolute paths to each file found. The soAllDirectories
flag tells it to search through subfolders recursively. So, you will end up with an array of paths at potentially different levels.
TPath.GetFileName()
strips off all folder path info, leaving just the file name.
Based on your example, you are searching recursively through C:\Main\
and you want to copy everything to C:\Main 1\
. When the search gives you the file C:\Main\Sub-Folder\File3.txt
, your use of TPath.GetFileName()
discards C:\Main\Sub-Folder\
, and so you concatenate C:\Main 1\
with just File3.txt
, thus you copy C:\Main\Sub-Folder\File3.txt
to C:\Main 1\File3.txt
instead of to C:\Main 1\Sub-Folder\File3.txt
.
That is why your subfolders are not copying correctly.
Rather than using TPath.GetFileName()
, you would need to replace only the Origin
portion of each returned absolute path (C:\Main\
) with the Destination
path (C:\Main 1\
), leaving everything else in the path intact. Thus, C:\Main\Sub-Folder\File3.txt
would become C:\Main 1\Sub-Folder\File3.txt
.
Otherwise, don't use soAllDirectories
at all. Recurse through the subfolders manually using TDirectory.GetDirectories()
instead, so that you are handling only 1 level of folders at a time.