2

激励例子:

在之前的会话中,应用程序已经存储了用户选择的一些路径。与此同时,该路径可能已被删除、移动、重命名或驱动器已卸载。应用程序现在想让用户通过 a 浏览路径,QFileDialog并且为了用户的方便,之前的路径作为文件对话框的起始目录传递,因为新路径可能在旧路径附近。不幸的是,如果 QFileDialog给定一个不存在的起始路径,它默认为当前工作目录,这不太可能对用户有帮助,因为它通常是应用程序的安装目录。

所以我们想预处理旧路径以指向一个实际存在的目录,然后再将其传递给QFileDialog. 如果旧路径不存在,我们想用最近的目录替换它。

那么如何获取文件路径(可能存在也可能不存在)并“向上”搜索该路径,直到找到文件系统中实际存在的东西?

4

2 回答 2

2

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

向上搜索直到路径存在:

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();
}
于 2018-10-11T17:03:56.863 回答
1

试试下面的代码:

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()返回指定路径的父目录的方法。循环代码直到满足现有路径最近两次迭代中的路径相同(这有助于我们避免无限循环)。

QFileInfo::dir()文档:

将对象的父目录的路径作为QDir对象返回。
注意:返回的QDir总是对应于对象的父目录,即使 QFileInfo 代表一个目录。

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

于 2018-10-12T13:22:53.797 回答