Название: Функция копирования папок с их содержимым!
Отправлено: kadr от Сентябрь 21, 2010, 07:34
Привет всем, у меня есть функция копирования папок с их содержимым, если копировать папку с файлами, то есть без вложенных папок, то копирует нормально, а если в папке есть вложенные подпапки, то происходит непонятные вещи, все содержимое всех папок копируется и как надо и как не надо! Поясню: 1. Все вхождения копируются аж 2 раза, сначало копируется все правильно, как должно, все файлы в нужных папках и папку тоже в нужных папках. 2. Потом почему то содержимое всех вложенных папок копируется в корень основной папки! Не пойму в чем дело, вот функция: bool Linux_Comander::CopyFolder(QString strFrom, QString strTo)//функция копирования папок с их содержимым. { QDir dir; //strFrom - имя папки, откуда копировать //strTo - имя папки, куда копировать
//убедимся, что имена заканчиваются слэшем, если нет - добавим if (strTo.right(1) != "") strTo += '/'; if (strFrom.right(1) != "") strFrom += '/';
//создаем ("копируем") текущую папку QDirIterator itr(strFrom,QDirIterator::Subdirectories); if (!dir.mkdir(strTo)) { QMessageBox::information(this,"Ошибка создания","Не удалось создать директорию "+strTo); return false; }
//будем перебирать все файлы и папки в текущей директории while(itr.hasNext()) { QString strFilePath = itr.next(); QString strFileTitle = itr.fileName();
//отсекаем "." и ".." if ((itr.fileName() != ".") && (itr.fileName() != "..") && (itr.fileName() != "")) { begin->setText("Из: "+strFilePath); end->setText("В: "+ strTo + strFileTitle);
if (itr.fileInfo().isDir()) { //рекурсивное погружение в найденную папку (strTo + strFileTitle) CopyFolder(strFilePath, strTo + strFileTitle); } else { QFile file(strFilePath),f(strTo + strFileTitle);
file.open(QIODevice::ReadOnly);//открываем его на чтение f.open(QIODevice::WriteOnly);//на запись qint64 bytes_write = 0; qint64 i = 0; bar->setMaximum(file.size());
while (!file.atEnd())//запускаем цикл в котором файл копируется построчно {
bytes_write = f.write(file.readLine());//построчное записывание i += bytes_write; bar->setValue(i);
} bar_all->setValue(full_size); full_size += f.size();
if (full_size >=1073741824) { bar_size->setText("Скопировано: "+ QString::number(full_size/1073741824) + " Gbyte"); } if (full_size >= 1048576) { bar_size->setText("Скопировано: "+ QString::number(full_size/1048576) + " Mbyte"); } if (full_size >= 1024) { bar_size->setText("Скопировано: "+ QString::number(full_size/1024) + " Kbyte"); } else { bar_size->setText("Скопировано: "+ QString::number(full_size) + " Byte"); }
} } }
return true; }
Название: Re: Функция копирования папок с их содержимым!
Отправлено: kramer3d от Сентябрь 21, 2010, 08:32
C++ (Qt) QDirIterator itr(strFrom,QDirIterator::Subdirectories);
создает итератор по всей иерархии папок на всю глубину вложенности, так что рекурсия здесь не нужна.
Название: Re: Функция копирования папок с их содержимым!
Отправлено: kadr от Сентябрь 22, 2010, 07:31
блин, никак не получается нормально скопировать папку с ее содержимым, все время какая то фигня не дает, я переделал маленько функцию, убрал рекурсию, а за место неё написал вот так: if (itr.fileInfo().isDir()) { strTo += strFileTitle; if (strTo.right(1) != "") { strTo += '/'; } if (!dir.mkdir(strTo)) { QMessageBox::information(this,"Ошибка создания","Не удалось создать временную директорию "+strTo); return false; } continue; } Впринципе копирует нормально только те папки, в которых одна подпапка, а если больше одной, то он копирует их друг в друга, то есть папка должна быть в корневой папке, а она оказывается в следущей, я нашел почему так происходит: strTo += strFileTitle; if (strTo_Vr.right(1) != "") { strTo += '/'; } надо как то возвращаться назад, после того как в этой папке больше ничего не осталось копировать, вернуться назад, я так понимаю, или может быть как то по другому это нужно делать, скажите в какую сторону думать то? Заранее спасибо!
Название: Re: Функция копирования папок с их содержимым!
Отправлено: Marat(Qt) от Сентябрь 22, 2010, 13:28
Странная функция... никаких там dir.cd, никаках dir.cdUp... Там везде абсолютные пути чтоли используются? Если да, то зачем? ___________________________ Виноват, поспешил. Итак, имеем итератор: QDirIterator it("/etc", QDirIterator::Subdirectories); while (it.hasNext()) { qDebug() << it.next();
// /etc/. // /etc/.. // /etc/X11 // /etc/X11/fs // ... } next () Advances the iterator to the next entry, and returns the file path of this new entry Как я понял, речь идет о полном пути, но есть функция QDirIterator::path() которая в данном примере должна вернуть что-то вроде "/etc", прибавим к этому "/" и вырежем "/etc/" из next, получим относительный путь, который можно и в mkdir кинуть. Ну а для QFile вроде не сложно тут полный путь состряпать, что-то вроде dir.absolutePath()+temp, где temp - относительное имя файла. Ну, может быть перед temp еще надо "/" поставить... в итоге обычный цикл вроде получается.
Название: Re: Функция копирования папок с их содержимым!
Отправлено: kadr от Сентябрь 23, 2010, 10:17
Спасибки, это действительно помогло!
Название: Re: Функция копирования папок с их содержимым!
Отправлено: kadr от Сентябрь 23, 2010, 11:01
У меня есть вот еще вопросик. При копировании файла или папки, вызывается функция в корой создается виджет с прогресс барами: void Linux_Comander::progress_bar()//функция отображения хода копирования { QVBoxLayout *laytbar = new QVBoxLayout; QVBoxLayout *layt_b = new QVBoxLayout; QVBoxLayout *layt_e = new QVBoxLayout; QVBoxLayout *layt_size = new QVBoxLayout; QHBoxLayout *layt_button = new QHBoxLayout; QHBoxLayout *layt_speed = new QHBoxLayout; QPushButton *close_but = new QPushButton; QPushButton *cancel_but = new QPushButton;
begin = new QLabel; end = new QLabel; bar_size = new QLabel; block_copy = new QLabel; speed = new QLabel; prog_dialog = new QWidget; bar = new QProgressBar; bar_all = new QProgressBar;
begin->setWordWrap(true); end->setWordWrap(true);
bar_size->setAlignment(Qt::AlignHCenter); block_copy->setAlignment(Qt::AlignHCenter); speed->setAlignment(Qt::AlignHCenter);
layt_b->addWidget(begin); layt_e->addWidget(end);
layt_speed->addWidget(block_copy); layt_speed->addWidget(speed); layt_speed->setAlignment(layt_speed,Qt::AlignHCenter);
layt_size->addWidget(bar_size); layt_size->addLayout(layt_speed);
layt_button->addWidget(close_but); layt_button->addWidget(cancel_but); layt_button->setContentsMargins(100,1,100,1);
laytbar->addLayout(layt_b); laytbar->addLayout(layt_e);
laytbar->addWidget(bar); laytbar->addWidget(bar_all);
laytbar->addLayout(layt_size); laytbar->addLayout(layt_button);
prog_dialog->setLayout(laytbar); prog_dialog->setWindowModality(Qt::WindowModal); prog_dialog->setGeometry((x/2)-(450/2),(y/2)-(140/2),450,140);//устанавливаем диалог в центре экрана prog_dialog->setStyleSheet("background-color: #CCCCCF");//цвет диалога prog_dialog->setWindowTitle("Копирование");//заголовок prog_dialog->setFont(QFont("",14,71));
bar_all->setMaximum(max_bar_all); bar->setAlignment(Qt::AlignHCenter); bar_all->setAlignment(Qt::AlignHCenter);
close_but->setText("Закрыть"); cancel_but->setText("Отменить");
prog_dialog->show(); connect(cancel_but,SIGNAL(clicked()),prog_dialog,SLOT(deleteLater())); connect(close_but,SIGNAL(clicked()),prog_dialog,SLOT(close()));
} вызываю я ее в самом начале функции bool Linux_Comander::CopyFolder(QString strFrom, QString strTo) { progress_bar(); .... .... .... } Но вот проблема, окно открывается и компаненты на нем появляются по мере использования, то есть, когда появляется сигнал заполнять прогресс бар, он появляется и начинает заполняться, два лабла в которых указаны пути откуда и куда копировать появляются только после тога как скопируется первый файл, и если он большой, то это напрягает, а кнопки вообще появляются в самом конце, когда все скопируется! В чем дело не пойму!
Название: Re: Функция копирования папок с их содержимым!
Отправлено: crossly от Сентябрь 23, 2010, 11:41
processEvents()
Название: Re: Функция копирования папок с их содержимым!
Отправлено: kadr от Сентябрь 23, 2010, 12:57
Название: Re: Функция копирования папок с их содержимым!
Отправлено: crossly от Сентябрь 23, 2010, 13:45
дык в асистенте написано...
Название: Re: Функция копирования папок с их содержимым!
Отправлено: Marat(Qt) от Сентябрь 24, 2010, 02:36
вызывай эту функцию, скажем, на каждой пятой итерации, ну или меньше, или больше... не знаю, самому не приходилось с ней работать. Идея такая: ты вызвал функцию copyFolder, пока она не выполнится, другие функции выполнятся не будут, обработчики событий, слоты, привязанные к сигналам, все они мирно ждут и бездействуют, пока не выполнится copyFolder, или пока их не вызовут явным образом. А если вызвать processEvents, то он быстренько выполнит обработку событий, выполнит слоты какие надо и вернется к копированию..
|