6

I am trying to remove all directories, subdirectories and the contained files from a specific path using boost::filesystem::remove_all(path). I also want to display an error message in case a file is open in another program. Does boost::filesystem::remove_all(path) throw an exception in this case?

Or is there another way I can achieve this?

AleC
  • 579
  • 3
  • 7
  • 15

4 Answers4

13

this does not fit in a comment so I'm posting as an answer

Just look in the source: http://www.boost.org/doc/libs/1_55_0/libs/filesystem/src/operations.cpp

  BOOST_FILESYSTEM_DECL
  boost::uintmax_t remove_all(const path& p, error_code* ec)
  {
    error_code tmp_ec;
    file_type type = query_file_type(p, &tmp_ec);
    if (error(type == status_error, tmp_ec, p, ec,
      "boost::filesystem::remove_all"))
      return 0;

    return (type != status_error && type != file_not_found) // exists
      ? remove_all_aux(p, type, ec)
      : 0;
  }

remove_all_aux is defined few lines above and so is remove_file_or_directory, remove_file, remove_directory and so forth and so on. The primitive operations are:

# if defined(BOOST_POSIX_API)
... 
#   define BOOST_REMOVE_DIRECTORY(P)(::rmdir(P)== 0)
#   define BOOST_DELETE_FILE(P)(::unlink(P)== 0)
...
# else  // BOOST_WINDOWS_API
...
#   define BOOST_REMOVE_DIRECTORY(P)(::RemoveDirectoryW(P)!= 0)
#   define BOOST_DELETE_FILE(P)(::DeleteFileW(P)!= 0)
...
# endif

The behavior of removing a locked file will be whatever your platform will provide.

Remus Rusanu
  • 288,378
  • 40
  • 442
  • 569
3

I am posting some code examples to clarify this issue. There are 2 scenarios.

In the first scenario I am using the remove_all function to delete the whole directory from a certain path and then I create a new directory at the same path:

try
{
if(exists(directory_path))
{
   remove_all(directory_path);
}
    create_directory(directory_path);   
}
catch(filesystem_error const & e)
{
    //display error message 
}

This works just as expected, but then I have a second scenario where I am trying to delete certain folders from a path and then create the new directory:

try
    {
        if(exists(directory_path))
        {
            for ( boost::filesystem::directory_iterator itr(directory_path); itr != end_itr; itr++)
            {
                std::string folder = itr->path().filename().string();
                if(folder == FOLDER1 || folder == FOLDER2 || folder == FOLDER3)     
                      remove_all(itr->path());
            } 
         }          
        create_directory(directory_path);   
    }
    catch(filesystem_error const & e)
    {    
                 //display error message
    }

In this case the exception is not thrown in case a file is open in another program. The files just get deleted. Why does this happen?

AleC
  • 579
  • 3
  • 7
  • 15
  • 1
    What OS? This is expected behavior on Linux, see [What happens to an open file handler on Linux if the pointed file gets moved, delete](http://stackoverflow.com/a/2031100/105929) – Remus Rusanu Jan 17 '14 at 09:12
  • I am using Windows 7 OS – AleC Jan 17 '14 at 09:35
  • the most likely explanation is that the file is not truly open at the moment you delete it. If a process has a handle on a file, it cannot be deleted. I must conclude no process has a handle on any of your files, if the delete succeeds. – Remus Rusanu Jan 17 '14 at 09:39
  • Why does it work in my first example, but not in my second example, given the same conditions? I can't figure it out.. – AleC Jan 17 '14 at 11:31
1

Example program in C++ that uses the Boost library to delete a directory

#include <boost/filesystem.hpp>

int main() {
    // replace with the name of the directory you want to delete
    const std::string dirname = "my_directory"; 
    boost::system::error_code ec;
    boost::filesystem::remove_all(dirname, ec);
    if (ec) {
        std::cerr << "Error deleting directory: " 
                  << ec.message() << std::endl;
        return 1;
    }
    return 0;
}

Note that the remove_all() function can also be used to delete files and non-empty directories. If you only want to delete an empty directory, you can use boost::filesystem::remove() instead. Also, make sure you have the Boost library installed and properly linked in your project.

0

It depends on which overload of remove_all you call; this is clearly documented in the documentation for the function. (What isn't clear is, if you use the function which reports errors by means of an error code, does the function continue, or does it return after the first error?)

James Kanze
  • 150,581
  • 18
  • 184
  • 329