Qt: Как найти ближайшего существующего предка пути, который сам может существовать или не существовать - PullRequest
0 голосов
/ 11 октября 2018

Пример мотивации:

В предыдущем сеансе приложение сохранило некоторый путь, выбранный пользователем.Тем временем этот путь мог быть удален, перемещен, переименован или диск отключен.Приложение теперь хотело бы позволить пользователю искать путь через QFileDialog, и для удобства пользователя предыдущий путь передается в качестве начального каталога файлового диалога, поскольку предположительно новый путь, вероятно, будет рядом со старымдорожка.К сожалению, если QFileDialog указан начальный путь, который не существует, по умолчанию используется текущий рабочий каталог, что вряд ли будет полезным для пользователя, поскольку обычно это каталог установки приложения.

Таким образом, мы хотели бы предварительно обработать старый путь, чтобы он указывал на каталог, который действительно существует, прежде чем передать его в QFileDialog.Если старый путь не существует, мы хотели бы заменить его на ближайший каталог, который делает.

Итак, как выбрать путь к файлу (который может существовать или не существовать) и выполнить поиск"вверх" по этому пути, пока не найдется что-то, что действительно существует в файловой системе?

Ответы [ 2 ]

0 голосов
/ 12 октября 2018

Попробуйте следующий код:

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() docs:

Возвращает путь родительского каталога объекта в виде объекта QDir.
Примечание: Возвращаемое QDir всегда соответствуетродительский каталог объекта, даже если QFileInfo представляет каталог.

Я все же рекомендую вам выполнить некоторые тесты, потому что я могу что-то упустить.

0 голосов
/ 11 октября 2018

Это два подхода, которые я придумала до сих пор, но предложения по улучшению очень приветствуются.

Поиск вверх, пока не найдется путь:

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();
}
...