Russian Qt Forum

Qt => Общие вопросы => Тема начата: Crazy Sage от Июнь 17, 2010, 14:53



Название: Создание цепочки каталогов
Отправлено: Crazy Sage от Июнь 17, 2010, 14:53
Подскажите, как грамотно сделать на C++\Qt3 следующую вещь.
По сути программа установки, пользователь вводит путь, мы туда распаковываем тгзшник.
Проблема в том, что пользователь может ввести несуществующие каталоги (ему предлагается как QFileDialog, так и введение адреса ручками в обычный QLineEdit)
Если несуществующий каталог один, то мы его создаем и все, но предположим что пользователь хочет установить в ~/qq/qq2, причем ни qq ни qq2 не существуют
mkdir qq/qq2 не работает, перебирать по разделителям весь путь, определять какой каталог еще существует, а с какого надо создавать, после чего создавать по одному, мне кажется нерациональным. Подскажите, есть ли более оптимальные способы или придется такой кодить?


Название: Re: Создание цепочки каталогов
Отправлено: lit-uriy от Июнь 17, 2010, 15:58
Не знаю, как в тройке, а в четвёрке это делается так:
bool QDir::mkpath ( const QString & dirPath ) const


Название: Re: Создание цепочки каталогов
Отправлено: Crazy Sage от Июнь 17, 2010, 20:34
В тройке я такой функции не вижу. А четверка мне недоступна.


Название: Re: Создание цепочки каталогов
Отправлено: lit-uriy от Июнь 18, 2010, 05:35
ну можно попробовать просто стянуть код из 4-ки
Посмотрел реализацию, она находится в QFSFileEngine
Для виндовоза:
Код
C++ (Qt)
bool QFSFileEngine::mkdir(const QString &name, bool createParentDirectories) const
{
   QString dirName = name;
   if (createParentDirectories) {
       dirName = QDir::toNativeSeparators(QDir::cleanPath(dirName));
       // We spefically search for / so \ would break it..
       int oldslash = -1;
       if (dirName.startsWith(QLatin1String("\\\\"))) {
           // Don't try to create the root path of a UNC path;
           // CreateDirectory() will just return ERROR_INVALID_NAME.
           for (int i = 0; i < dirName.size(); ++i) {
               if (dirName.at(i) != QDir::separator()) {
                   oldslash = i;
                   break;
               }
           }
           if (oldslash != -1)
               oldslash = dirName.indexOf(QDir::separator(), oldslash);
       }
       for (int slash=0; slash != -1; oldslash = slash) {
           slash = dirName.indexOf(QDir::separator(), oldslash+1);
           if (slash == -1) {
               if(oldslash == dirName.length())
                   break;
               slash = dirName.length();
           }
           if (slash) {
               QString chunk = dirName.left(slash);
               bool existed = false;
               if (!isDirPath(chunk, &existed) && !existed) {
                   if (!mkDir(chunk))
                       return false;
               }
           }
       }
       return true;
   }
   return mkDir(name);
}
 
для *nix'ов:
Код
C++ (Qt)
bool QFSFileEngine::mkdir(const QString &name, bool createParentDirectories) const
{
   QString dirName = name;
   if (createParentDirectories) {
       dirName = QDir::cleanPath(dirName);
       for(int oldslash = -1, slash=0; slash != -1; oldslash = slash) {
           slash = dirName.indexOf(QDir::separator(), oldslash+1);
           if (slash == -1) {
               if (oldslash == dirName.length())
                   break;
               slash = dirName.length();
           }
           if (slash) {
               QByteArray chunk = QFile::encodeName(dirName.left(slash));
               QT_STATBUF st;
               if (QT_STAT(chunk, &st) != -1) {
                   if ((st.st_mode & S_IFMT) != S_IFDIR)
                       return false;
               } else if (::mkdir(chunk, 0777) != 0) {
                       return false;
               }
           }
       }
       return true;
   }
#if defined(Q_OS_DARWIN)  // Mac X doesn't support trailing /'s
   if (dirName[dirName.length() - 1] == QLatin1Char('/'))
       dirName = dirName.left(dirName.length() - 1);
#endif
   return (::mkdir(QFile::encodeName(dirName), 0777) == 0);
}
 


Название: Re: Создание цепочки каталогов
Отправлено: Crazy Sage от Июнь 18, 2010, 07:16
Порывшись в манах нашел более топорный метод - у линуксовского mkdir есть ключ -p, о котором я не знал, которые это и делает. Выполняю его через system и всех делов.