【问题标题】:C++ ReadDirectoryChangesW and Boost returns dir change as File (OLD NAME)C++ ReadDirectoryChangesW 和 Boost 将目录更改作为文件(旧名称)返回
【发布时间】:2017-07-24 09:08:16
【问题描述】:

我有一个应用程序正在监视目录的变化。但是,当我重命名目录时,假设将目录 A 更改为目录 B,我将看到以下输出结果:

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

虽然我期待输出:

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

这种情况也发生在删除目录时,给出输出:

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

虽然我期待输出:

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

我用来获得这个输出的代码(使用 Boost 的文件系统)是:

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;
    }

我在这里做错了什么?

【问题讨论】:

  • @HansPassant,实际上不会。正如文档所述,它将返回受监控目录的相对路径。

标签: c++ boost boost-filesystem readdirectorychangesw


【解决方案1】:

问题在于,在这两种情况下,您都不会收到通知,直到该目录不再被称为 C:\A(因为它已被删除或移动)。所以当你去的时候:

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

is_directory 返回false(所以你将Type 保留为"File"

我建议改为:

const std::string Type = boost::filesystem::is_directory(path)    ? "Directory" :
                         boost::filesystem::is_regular_file(path) ? "File" :
                                                                    "unknown";

【讨论】:

  • 感谢您的回复。那么当目录已经被删除时会触发通知?所以如果我添加一个 FileExists 它会消除那些(意外的)结果?
  • 是的,但是因为在确定类型时路径不存在,所以会返回未知而不是目录?我必须根据文件或目录触发一些操作。那么,当路径不是以文件名和扩展名结尾时,假设它是一个目录有多安全?文件/目录是否仍然存在与调用的操作无关,因为它会同步数据库
  • 您无法从路径名中判断路径是文件还是目录。尝试将 C:\A\b 创建为纯文件并将其删除。也许您可以在数据库中查看旧类型?我认为这是一个 X-Y 问题 - 请针对您的 实际 问题提出另一个问题。
  • 感谢您的建议。这更安全,因为如果它不被 boost 视为常规文件,它将永远不会返回 File。 boost 什么时候会真正将文件路径视为常规文件?
猜你喜欢
  • 2017-05-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多