Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

CDiskObject: Simplifying common disk operations

0.00/5 (No votes)
11 Oct 2006 2  
A class for common directory and file list operations.

Sample Image - diskobject.gif

Introduction

Some common disk operations are inexplicably tedious to accomplish in code: getting a list of all CPP-files from a directory, getting a list of files in a directory subtree, copying a directory subtree, or getting all EXE-files from a subtree. CDiskObject simplifies some of those common operations.

Using the code

The class is very simple to use. Instantiate a CDiskObject, and call away! If the ctor is called with a CWnd-pointer, the window pointed to will be used for feedback. The feedback is normally files or directories processed, and error messages.

TRUE is returned if functions are successful. GetErrorMessage can be called to get an error message otherwise, except for FileExists, which returns FALSE if the file doesn't exist - a quite normal case.

The public functions are:

Files

  • BOOL FileExists( CString file )

    Returns TRUE if the file 'file' exists.

  • BOOL CreateFile( CString file )

    Creates the empty file 'file'. If 'file' contains a non-existing subdirectory, it will be created.

  • BOOL CopyFile( CString sourceFile, CString destDirectory )

    Copies 'sourceFile' to 'destDirectory'. 'destDirectory' will be created if it doesn't exist.

  • BOOL CopyFiles( CString sourceDirectory, CString destDirectory)

    Copies all files from 'sourceDirectory' to 'destDirectory'. Subdirectories are not copied (use CopyDirectory, described below, for this). 'destDirectory' will be created if it doesn't exist.

  • BOOL CopyFiles( CStringArray& files, CString destDirectory)

    Copies the files in 'files' to 'destDirectory'. Either the filenames in 'files' must be fully qualified or will be copied from the current directory. 'destDirectory' will be created if it doesn't exist.

Directories

  • BOOL CreateDirectory( CString directory )

    Creates 'directory'. Subdirectories will also be created.

  • BOOL CopyDirectory( CString sourceDirectory, CString destDirectory)

    Copies the contents from 'sourceDirectory' to 'destDirectory'. Subdirectories will not be copied.

  • BOOL EmptyDirectory( CString directory )

    Deletes all files from 'directory'. Subdirectories will not be emptied.

  • BOOL RemoveDirectory( CString directory )

    Remove 'directory' even if it is not empty. Will not remove subdirectories.

  • BOOL CopyDirectories( CString sourceDirectory, CString destDirectory)

    Copies the contents from 'sourceDirectory' to 'destDirectory'. Subdirectories will also be copied.

  • BOOL EmptyDirectories( CString directory )

    Deletes all files from 'directory'. Subdirectories will also be emptied.

  • BOOL RemoveDirectories( CString directory )

    Removes 'directory' even if it is not empty. Will also remove subdirectories.

Enumerations

  • BOOL EnumDirectories( CString sourceDirectory, CStringArray& directories )

    Returns a list of all subdirectories in 'sourceDirectory' in 'directories'. Subdirectories will not be enumerated.

  • BOOL EnumFilesInDirectoryWithFilter( CString filter, CString sourceDirectory, CStringArray& files, int mode = EF_ONLY_FILENAMES)

    Returns a list of all files in 'sourceDirectory' matching the filter in 'filter' in 'files'. If mode is EF_ONLY_FILENAMES (default), only the filenames will be returned. If mode is EF_FULLY_QUALIFIED, the filenames will contain the complete path. Subdirectories will not be searched.

  • BOOL EnumFilesInDirectory( CString sourceDirectory, CStringArray& files, int mode = EF_ONLY_FILENAMES )

    Returns a list of all files in 'sourceDirectory' in 'files'. If mode is EF_ONLY_FILENAMES (default), only the filenames will be returned. If mode is EF_FULLY_QUALIFIED, the filenames will contain the complete path.

  • BOOL EnumAllFiles( CString sourceDirectory, CStringArray& files )

    Returns a list of all files in 'sourceDirectory' in 'files'. The filenames will contain the complete path. Subdirectories will also be searched.

  • BOOL EnumAllFilesWithFilter( CString filter, CString sourceDirectory, CStringArray& files )

    Returns a list of all files in 'sourceDirectory' in 'files' matching 'filter'. The filenames will contain the complete path. Subdirectories will also be searched.

Error handling

  • CString GetErrorMessage()

    Returns an error string in case of an error. If a feedback window is submitted to the ctor, the error message will be displayed there as well.

See the downloadable documentation for additions.

Points of Interest

First of all, a warning. Wiping out a directory subtree is not exactly funny; if it so happens, it was not the expected subtree that got removed. Beware!

Second, the same warning again. EmtpyDirectories or RemoveDirectories will make you very, very unhappy if it happens to point to a directory you did not expect.

This class should really be a collection of static functions, but for different reasons, I wanted to keep a separate error string for each object. I toyed with a version where I added more data members, source directory, destination directory, source file, accessors to those, and reduced the number of in-parameters to the operations instead. It looked better on paper. In practical use, however, the class got harder to use, not easier. I had to call a few functions to set up the class and then apply the operation. It was far too easy to get one of, say, four calls wrong than one single one...

History

  • The Dark Ages

    Initial version.

  • 14/4 2004

    Time for an update. The following has been added:

    • Added const-correctness for in params. Even though CStrings will be copied and the multi-meg systems of today will hardly notice a few more strings, the class will be cumbersome to use in a const-correct environment. And that defeats the purpose...
    • Replacing "/" with "\" when qualifying file names/directories. Shameful oversight on the part of an old DOS-grunt.
    • Added pragma to get rid of the C4706 assignment warning. De-pragma warnings are not exactly a good practice, but neither is the extra code necessary to do tests. I don't assume that my computer will run out of letters anytime soon, but nonetheless, extra code lines add up, and wading through a ton of assignments can easily take the concentration away from more important parts of the code. This is a tricky question, however, readability, maintainability, and such stuff. Finally, it's a matter of personal preference. The good thing with a free source is that you are allowed to rewrite it if you don't like it!
    • Added RemoveFile for reasons of symmetry. The API already has a ::DeleteFile, but as it is simple to add a wrapper, why not?
  • 15/5 2004

    Added a demo-project. The demo project is just that, a demo (see the picture), and no attempt to write an Explorer replacement :-) Note that the application will move and delete directories, and there is no way to undo a removal of a directory branch. So please be careful, I already have lots of doubts doing a demo project - can I live with someone inadvertently wiping out important files? I guess I have to, but you have been warned. Warn, warn. Twice.

  • 24/6 2004

    Long overdue, here comes another update. Based on feedback from Amit Pitaru, I've added a default ctor due to CodeWarrior complaining. A CodeWarrior version of the demo project was also created by Amit (included in the downloads). This is the community spirit - thanks a lot for the help! It is far too easy to forget that MFC can be used in other environments.

    Finally, I've included an HTML-documentation for both the class and the demo project.

  • 6/8 2004
    • Added a _T() macro to the default parameter of SetSystemErrorMessage (nuhi).
    • Changed the size of the drive buffer from _MAX_DRIVE to _MAX_PATH (jkaspzyk).
  • 25/3 2005

    Browse-buttons added to the listboxes in the small demo-application (WREY). This allows running against other computers, for example.

  • 17/4 2005

    Some good additions from Allen Rossouw added to the class:

    • EnumFilesInDirectoryWithFilter returns the file list sorted alphabetically.
    • DirectoryExists added, returning TRUE if a given directory exists.
    • A version of CopyFile allowing copying to a file, with a new name added.
    • FileInformation added, returning a BY_HANDLE_FILE_INFORMATION for the given file added.

    A big thanks to Allen for the help!

  • 15/5 2005

    A bug-correction, and two more members this time:

    • Corrected bug using the wrong variable in CopyFile (Lorenzo H. Mart�n).
    • Added RenameFile (Lorenzo H. Mart�n).
    • Added MoveFile.
  • 19/6 2005
    • A non-MFC version of the class added, CStdDiskObject. This class uses std::string/std::wstring and std::vector instead of Cstring and CStringArray, and the C-runtime file-handling functions instead of the Windows API-versions. All the thanks for this go to the Webdude, David Mackay, both for getting me started on this and for the testing assistance. I've included his test file, which will show the usage of many of the functions in a console application.

      Note: only the source file Zip is updated in this batch, not the demo application, documentation, or other stuff.

  • 16/7 2006
    • Numerous small corrections, and a big thanks to all who have contributed reports below, as well as to the incomparable Webdude. Webdude lies behind the delightful little test application for the non-MFC version of the project.
  • 1/10 2006
    • Some bug corrections (most notably in the Create directory functionality).

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here