Почему QFile не может читать из каталога "~"?
Я попробовал следующий короткий пример, чтобы узнать об ошибке в большой программе, над которой я работаю. Похоже, QFile не поддерживает нотацию unix (или оболочки) для домашнего каталога:
#include <QFile>
#include <QDebug>
int main()
{
QFile f("~/.vimrc");
if (f.open(QIODevice::ReadOnly))
{
qDebug() << f.readAll();
f.close();
}
else
{
qDebug() << f.error();
}
}
Как только я заменяю "~" моим реальным домашним каталогом, он работает. Есть ли простой обходной путь - какую-то настройку включить? Или я должен пойти по "уродливому" пути и спросить у QDir домашний каталог текущего пользователя и добавить его вручную к каждому пути?
Приложение: Понятно, что обычно оболочка выполняет расширение тильды, поэтому программы никогда этого не увидят. Тем не менее, это так удобно в оболочках Unix, что я надеялся, что реализация Qt для доступа к файлам включит это расширение.
4 ответа
Почему бы просто не создать вспомогательную функцию, что-то вроде (не проверено):
QString morphFile (QString s) {
if (s.startsWith ("~/"))
s.replace (0, 1, QDir::homePath());
return s;
}
:
QFile f(morphFile ("~/.vimrc"));
Более полное решение может быть (снова непроверенным, так как у меня нет Qt локально, но компетентный кодировщик должен быть в состоянии это сделать):
QString morphFile (QString fspec) {
// Leave strings not starting with tilde.
if (!fspec.startsWith ("~"))
return fspec;
// Special case for current user.
if (fspec.startsWith ("~/")) {
fspec.replace (0, 1, QDir::homePath());
return fspec;
}
// General case for any user. Get user name and length of it.
QString name (fspec);
name.replace (0, 1, "");
int len = name.indexOf ('/');
if (len == -1)
len = name.length()
else
len--;
name = name.left (idx);
// Find that user in the passwd file, replace with home directory
// if found, then return it.
struct passwd *pwent = getpwnam (name.toAscii().constData());
if (pwent != NULL)
fspec.replace (0, len+1, pwent->pw_dir);
return fspec;
}
Это не имеет ничего общего с не поддержкой UNIX; расширение тильд в домашний каталог пользователя - это замена, выполняемая оболочкой, так что да, вам придется заменить их вручную.
Пожалуйста, отправьте предложение в багтрекер Qt.
Взгляните на функцию библиотеки C glob
, который будет выполнять расширение тильды (и, возможно, расширение подстановочных знаков и различные другие функции).