Copy everything from a source directory to a new directory Delphi EX7

14.9k Views Asked by At

My end goal is to copy all the relevant files from one folder to another. So e.g. we have C:\Users\Tool\Desktop\test\oldStuff. In the folder oldStuff we have more folders as well as some mp3,mp4 and txt files.

Now what I would like to do is copy all the mp4 files that are smaller than a GB to C:\Users\Tool\Desktop\test\New_Stuff_Less_than_a_Gig, and the .mp4 files that are bigger than a GB to C:\Users\Tool\Desktop\test\New_STuff_Bigger_than_a_Gig.

I though is this would be pretty easy but I was wrong. So far have this, didn't worry about file type for now so just made it *.*

 procedure TForm4.Button1Click(Sender: TObject);
 var
   f: TSearchRec;
   Dir: string;
 begin
    if not SelectDirectory(Dir,widestring(Dir),Dir) then   Exit;
    FileMode:=0;
    if FindFirst(Dir+'\*.*',faAnyFile,f) = 0 then
    repeat
         try
          if (f.Attr and faDirectory ) < $00000008 then
          CopyFile(PChar(Dir+'\'+f.Name),PChar
 ('C:\Users\Tool\Desktop\test\new\'+f.Name),false);
         except
          on e: exception do
            ShowMessage(E.Message);
         end;
    until findNext(f) <> 0
 end;

which will copy anything in the folder that is selected but it doesn't copy anything from the folders within the selected folder. E.g. if we have C:\Users\Tool\Desktop\test\oldStuff\movie.mp4 it will copy the Movie.mp4 file but if we have C:\Users\Tool\Desktop\test\oldStuff\movies\Movie.mp4 it won't copy the Movie.mp4 file. I though I could just do something like this

CopyFile.size < 1000 (PChar('C:\Users\Tool\Desktop\test\oldStuff\*.*'+f.Name),
                   PChar('C:\Users\Tool\Desktop\test\new_Stuff\'+f.Name),false)

or even just

CopyFile (PChar('C:\Users\Tool\Desktop\test\old\*.*'+f.Name),
                   PChar('C:\Users\Tool\Desktop\test\new\'+f.Name),false);

but it didn't copy anything.

1

There are 1 best solutions below

12
Ken White On BEST ANSWER

Here's an example (done in XE7) that will do what you want. You'll need to modify it to suit your needs, obviously; it has hard-coded path information and file mask (*.png) and uses a constant to decide whether the file is large or small.

It's based on this sample directory tree:

D:\TempFiles
  |--\Test
  |-----\A
  |-----\B
  |--------\SubB   
  |-----\NewFiles
  |-------\Large
  L-------\Small

It finds all of the .png files in D:\TempFiles\Test and it's subfolders, and copies the ones equal to or larger than 10KB to D:\TempFiles\NewFiles\Large and the ones smaller than 10KB to D:\TempFiles\NewFiles\Small.

You'll need to add IOUtils and Types to your implementation uses clause.

procedure TForm1.Button1Click(Sender: TObject);
var
  aLargeFiles: TStringDynArray;
  aSmallFiles: TStringDynArray;
const
  LargeSize = 10 * 1024;
  SourcePath = 'D:\TempFiles\Test\';
begin
  aLargeFiles := TDirectory.GetFiles(SourcePath, '*.png',
                   TSearchOption.soAllDirectories,
                   function (const Path: string; const SR: TSearchRec): Boolean
                   begin
                     Result := (SR.Size >= LargeSize);
                   end);
  aSmallFiles := TDirectory.GetFiles(SourcePath, '*.png',
                   TSearchOption.soAllDirectories,
                   function(const Path: string; const SR: TSearchRec):Boolean
                   begin
                     Result := (SR.Size < LargeSize);
                   end);
  CopyFilesToPath(aLargeFiles, 'D:\TempFiles\NewFiles\Large\');
  CopyFilesToPath(aSmallFiles, 'D:\TempFiles\NewFiles\Small\');
end;

procedure TForm1.CopyFilesToPath(aFiles: array of string; DestPath: string);
var
  InFile, OutFile: string;
begin
  for InFile in aFiles do
  begin
    OutFile := TPath.Combine( DestPath, TPath.GetFileName( InFile ) );
    TFile.Copy( InFile, OutFile, True);
  end;
end;