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.
我仍然建议你运行一些测试,因为我可能会遗漏一些东西。
激励示例:
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, ifQFileDialog
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: TheQDir
returned always corresponds to the object's parent directory, even if the QFileInfo represents a directory.
我仍然建议你运行一些测试,因为我可能会遗漏一些东西。