Copy Folder Test

[Home]   [Projects]    [Delphi Techniques]   [Math Topics]   [Library]   [Utilities]

 

Available Now

Search

Google
 

Search WWW             

Search delphiforfun.org

Contact

Feedback:  Send an e-mail with your comments about this program (or anything else).

Help support DFF

 If you benefit from the website,  in terms of knowledge, entertainment value, or something otherwise useful, consider making a donation via PayPal  to help defray the costs.  (No PayPal account necessary to donate via credit card.)  Transaction is secure.

 

Google
 

Search WWW

Search delphiforfun.org

 

 

Problem Description

Required: A program to copy all of the files matching a file mask to a different folder. 

Background & Techniques

I recently had need for a procedure to copy all files in a CD folder  to a new folder on a hard disk drive and reset the "ReadOnly" attributes.   . 

This program was written to test the resulting new  "CopyFolder" function, but it seems that the program has enough features to perhaps serve as a useful utility for non-programmers..

Usage is straight-forward: Select an input folder and an output folder.  The output folder may be existing or a new one.  Other options include:

  • Set a file mask to control which files get selected.  A separate "file masks" page defines masking string options and provides a few examples.
  • Set the scope of the operations  - files in the input folder only or input folder plus all files in folders contained within the input folder.
  • Whether to retain or reset the  "readonly" attribute on the copied files.
  • How to handle duplicate files, i.e. files already existing in the target folder.  options are
    • Ignore the file, do not copy.
    • Copy the file, replacing the existing file in the the target folder.
    • Copy the file only if the source file is newer than the target.
    • Ask the user whether to overwrite the existing target file.

Click the "Copy" button to complete the operation.  A list of files copied and the total count will be displayed when the operation has been completed.

You may interrupt the operation by clicking the "Stop" button but the copies of files already processed will remain in the output folder.  If you select "Ask" option for the Duplicate Files radio group, a reply of "Cancel" when asked will also stop the operation.
 

Non-programmers are welcome to read on, but may want to skip to the bottom of this page to download executable version of the program.

Notes for Programmers

The program calls the "CopyFolder" function contained in unit UCopyFolder.pas to do most of the work.   CopyFolder copies files matching a given mask from one folder to another. Parameters are;

  • FromFolder: The path to the folder containing the files to be copied
  • ToFolder: The path to the folder to receiver the files
  • Mask: A file mask to control which files are selected ('*.*' = All files)
  • DupFileOpts: Four numeric options are available when the file already exists:
    • 0 ==> skip the file
    • 1 ==> always copy the file
    • 2 ==> copy the file if it is newer than the existing copy
    • 3 ==> ask the user what action to take
  • CopySubFolders: Files in subfolders of the specified FromPath folder will also be copied if this parameter is true.
  • ResetReadOnly: If true, input files marked as "Readonly" will have that attribute removed in the target location.
  • FileExit: The address of optional method (function of object) specifying a user function to be called before each file is copied.  If the callback procedure is specified, it receives 4 parameters:
    • Inpath: Path to the input file.
    • OutputPath: Path where the file will be copied.
    • Filename: Name of the file to be copied.
    • Cancopy: Boolean parameter with a default value of true. Set "Cancopy" to false to skip copying this file.

FileExit should  return a result value of true if copying is to continue,  and false to abort the copy procedure without copying further files.

 

CopyFolder uses a few techniques worth describing for future reference

  • Recursive search through a folder and subfolders is a technique we have used before but filtering files with a file mask makes the procedure a little more complicated.  The FindFirst function can filter returned records based on a specified file mask, but since we will likely be recursively calling CopyFolder  with subdirectories of the input directory, FindFirst must search all file names (with a file name mask of "*.*")
  • File mask matching - FindFirst and successive FindNext calls  retrieve file information in a TSearchrec for each call including the file name, date, attributes .  The Name field is passed to the MatchesMask function along with the user specified mask.  I could find no user oriented description of mask strings, so I added a tab sheet to the program with the mask  fields described and a few examples.  
  • Overloading a function or procedure with an optional method call - I decided to provide an optional callback function passed as a parameter to CopyFolder.  The callback function is called for each file to be copied,  passing the parameters described above.  The typical way to make a parameter optional is to provide an overloaded version without the optional parameter  and from there call the "real" version with a default value for the missing parameter.  (Delphi recognizes the keyword "overload" in the procedure definition and will accept multiple definitions with the same name so long as the parameter lists are different.)  The tricky part here is that we cannot pass a "Nil" (no address) value for the callback function because the function is defined as a method type  function "of object" meaning that it is a method of an object.   Method type functions are passed as a pair of pointers, a pointer to the function code and a a pointer to the class instance to which it belongs.    I got around the problem by defining a DummyFileExit function within a TDummyClass definition.  And an instance if TDummyClass named DummyClass.  This DummyfFileExit may now be passed as the default FileExit for cases where the user chose not to provide one.  CopyFile checks and ignores any reference to DummyFileExit, so it is not necessary to actually create the DummyClass instance.   Whew!     
  • Changing file attributes - I only way i could find to reset the ReadOnly attribute was to copy the (using the Windows CopyFile funtion) and then use the SetFileAttr function to reset the attribute if in was set in the input.

Running/Exploring the Program 

Suggestions for Further Explorations

I Is there a more direct way to make a method pointer an optional parameter in a function call?

 

Original Date: October 30 2006

Modified: February 01, 2007

 


  [Feedback]   [Newsletters (subscribe/view)] [About me]
Copyright © 2000-2008, Gary Darby    All rights reserved.