Почему QFile не может читать из каталога "~"? - PullRequest
5 голосов
/ 12 мая 2010

Я попробовал следующий короткий пример, чтобы узнать об ошибке в более крупной программе, над которой я работаю. Похоже, 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 ]

9 голосов
/ 12 мая 2010

Почему бы просто не создать вспомогательную функцию, что-то вроде (не проверено):

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;
}
3 голосов
/ 12 мая 2010

Это не имеет ничего общего с не поддержкой UNIX; расширение тильд в домашний каталог пользователя - это замена, выполняемая оболочкой, так что да, вам придется заменить их вручную.

2 голосов
/ 12 мая 2010

Пожалуйста, отправьте предложение в систему отслеживания ошибок Qt.

https://bugreports.qt.io/

0 голосов
/ 12 мая 2010

Взгляните на библиотечную функцию C glob, которая будет выполнять расширение тильды (и, возможно, расширение подстановочных знаков и другие различные функции).

...