0

I have an application which is monitoring directories for changes. However, when I rename a directory, lets say Directory A into Directory B, than I will see the following output results:

File renamed (OLD): C:\A
Directory renamed (NEW): C:\B

while I expect the output:

Directory renamed (OLD): C:\A
Directory renamed (NEW): C:\B

This occasion is also occurring on deleting a directory, giving the output:

File removed: C:\A\test.txt
File modified: C:\A
File removed: C:\A

while I expect the output:

File removed: C:\A\test.txt
Directory modified: C:\A
Directory removed: C:\A

The code I use to get to this output (using Boost's FileSystem) is:

while(true) {
    FILE_NOTIFY_INFORMATION* info = reinterpret_cast<FILE_NOTIFY_INFORMATION*>(p);
    int ret = ::WideCharToMultiByte(CP_ACP, 0, info->FileName, info->FileNameLength / sizeof(WCHAR), FilePathChar, sizeof(FilePathChar), NULL, NULL);
    stringstream FilePathStream;
    FilePathStream << argv[1];
    FilePathStream << "\\";
    FilePathStream << FilePathChar;
    string FilePath = FilePathStream.str();
    cout << FilePath << endl;
    boost::filesystem::path path(FilePath);
    string Type = "File";
    if (boost::filesystem::is_directory(path)) {
        Type = "Directory";
        }
    ofstream myfile;
    myfile.open("changes.txt", std::ios_base::app);
    switch (info->Action) {
        case FILE_ACTION_ADDED:
            myfile << Type << " added: " << FilePath << "\n";
            break;
        case FILE_ACTION_MODIFIED:
            myfile << Type << " modified: " << FilePath << "\n";
            break;
        case FILE_ACTION_REMOVED:
            myfile << Type << " removed: " << FilePath << "\n";
            break;
        case FILE_ACTION_RENAMED_NEW_NAME:
            myfile << Type << " renamed (NEW): " << FilePath << "\n";
            break;
        case FILE_ACTION_RENAMED_OLD_NAME:
            myfile << Type << " renamed (OLD): " << FilePath << "\n";
            break;
        default:
            myfile << Type << " UNDISCOVERED ACTION: " << FilePath << "\n";
            break;
        }
    myfile.close();
    ::memset(FilePathChar, '\0', sizeof(FilePathChar));
    if (!info->NextEntryOffset) break;
    p += info->NextEntryOffset;
    }

What am I doing wrong here?

TVA van Hesteren
  • 1,031
  • 3
  • 20
  • 47

1 Answers1

2

The problem is that in both cases you don't get the notification until the directory is no longer called C:\A (either because it has been deleted or moved). So when you go:

if (boost::filesystem::is_directory(path)) {
    Type = "Directory";
}

is_directory returns false (so you leave Type as "File")

I suggest instead:

const std::string Type = boost::filesystem::is_directory(path)    ? "Directory" :
                         boost::filesystem::is_regular_file(path) ? "File" :
                                                                    "unknown";
  • Thanks for your reply. So the notification is triggered when the directory is already removed? So if I add a FileExists it would eliminate those (unexpected) results? – TVA van Hesteren Jul 24 '17 at 09:35
  • Right, but that will return unknown instead of Directory since the path doesn't exist when type is being determined? I have to trigger some actions based on File or Directory. So, when the path is not ending with a filename and extension, how safe is it to assume it is a directory? It is irrelevant for the operation that is called whether the file / directory still exists, since it will sync a database – TVA van Hesteren Jul 24 '17 at 09:42
  • You can't tell from the pathname whether a path was a file or a directory. Try creating C:\A\b as a plain file and deleting it. Perhaps you can look in the database to see the old type? I think this is an X-Y problem - ask another question with your *actual* problem. – Martin Bonner supports Monica Jul 24 '17 at 09:48
  • Thanks for your suggestion. This is more safe since it will never return File if it isn't considered a regular file by boost. When will boost consider a file path to be a regular file actually? – TVA van Hesteren Jul 24 '17 at 09:55