Qt:如何找到路径的最近的现有祖先,它本身可能存在也可能不存在

Qt: How to find the nearest existing ancestor of a path, which itself may or may not exist

激励示例:

In a previous session, the application has stored some path selected by the user. In the meantime that path may have been deleted, moved, renamed or the drive unmounted. The application would now like to let the user browse for a path via a QFileDialog and for the user's convenience, the previous path is passed as the starting directory of the file dialog, as presumably the new path is likely to be near the old path. Unfortunately, if QFileDialog is given a starting path that does not exist, it defaults to the current working directory, which is very unlikely to be helpful to the user as it is typically the installation directory of the application.

So we would like to preprocess the old path to point to a directory that actually exists before passing it to QFileDialog. If the old path doesn't exist, we'd like to replace it with the nearest directory that does.

那么如何获取文件路径(可能存在也可能不存在)并搜索 "up" 该路径直到找到文件系统中实际存在的内容?

这是我到目前为止提出的两种方法,但非常感谢您提出改进建议。

向上搜索直到路径存在:

QString GetNearestExistingAncestorOfPath(const QString & path)
{
    if(QFileInfo::exists(path)) return path;

    QDir dir(path);
    if(!dir.makeAbsolute()) return {};
    do
    {
        dir.setPath(QDir::cleanPath(dir.filePath(QStringLiteral(".."))));
    }
    while(!dir.exists() && !dir.isRoot());

    return dir.exists() ? dir.path() : QString{};
}

向下搜索直到路径不存在:

QString GetNearestExistingAncestorOfPath(const QString & path)
{
    if(QFileInfo::exists(path)) return path;

    auto segments = QDir::cleanPath(path).split('/');
    QDir dir(segments.takeFirst() + '/');
    if(!dir.exists()) return {};
    for(const auto & segment : qAsConst(segments))
    {
        if(!dir.cd(segment)) break;
    }
    return dir.path();
}

试试下面的代码:

QString getNearestExistingPath(const QString &path)
{
    QString existingPath(path);
    while (!QFileInfo::exists(existingPath)) {
        const QString previousPath(existingPath);
        existingPath = QFileInfo(existingPath).dir().absolutePath();
        if (existingPath == previousPath) {
            return QString();
        }
    }
    return existingPath;
}

此函数利用QFileInfo::dir()方法,其中returns指定路径的父目录。代码循环直到满足现有路径 最近两次迭代中的路径相同(这有助于我们避免无限循环)。

来自 QFileInfo::dir() 文档:

Returns the path of the object's parent directory as a QDir object.
Note: The QDir returned always corresponds to the object's parent directory, even if the QFileInfo represents a directory.

我仍然建议你运行一些测试,因为我可能会遗漏一些东西。