Home > Software engineering >  How to copy a folder and keep the structure?
How to copy a folder and keep the structure?

Time:04-27

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.

  • Related