PDA

View Full Version : Uploading of Entire Directory(with subdirectories and files) - Please Help



msimurin
13th July 2010, 04:07
Hi, this is the problem i v been struggling with now for a while and i kinda feel desparate. I am trying to upload directory with all of its contest in my small ftp client app but just when it looks as everything works some small bug slips in. Here is my code so please take a look




void FtpWindow::upload_slot(){

QString name = homefileList->currentItem()->text(0); // Here i get dir name from the treewidgetlist selected item


QString filepath = path.absoluteFilePath(name); // Since path is changed each time i click on a directory in treewidget and enter it, here is how i get the path of directory i want to upload



if (!isHomeDir.value(name)) {uploadFile(filepath, name);} // this is just checking if its dir or file

else { uploadDirectory(filepath, name); }

ftp->list();
}


void FtpWindow::uploadFile(const QString& filePath, const QString &name)

{

QFile *file = new QFile(filePath);
if ( !file->open(QIODevice::ReadOnly) ) {
QMessageBox::critical( this, tr("Upload error"),
tr("Can't open file '%1' for reading.").arg(filePath) );
delete file;
return;
}
ftp->put(file, name);
}

void FtpWindow::uploadDirectory(const QString& dirPath, const QString &name)

{

QDir targetDir(dirPath);



uploadPath = currentPath;
qDebug() << uploadPath;

ftp->mkdir(name);
ftp->cd(name);




QDirIterator it(targetDir, QDirIterator::Subdirectories);


while (it.hasNext()) {

QFileInfo info = it.next();




if(it.fileName() == "." | it.fileName() == ".." | it.fileName() == "/") continue;

if(info.isDir()) {
info.dir().absolutePath();


QString dirpath = info.absoluteFilePath().remove(0, info.absoluteFilePath().indexOf('/'+ name));

QString parentdir = uploadPath + dirpath.left(dirpath.lastIndexOf('/'));
qDebug() << dirpath << "is dir and it's parent dir is " << parentdir ;

ftp->cd(parentdir);
ftp->mkdir(info.baseName());


}

else {

QString fajlovi = info.absoluteFilePath().remove(0, info.absoluteFilePath().indexOf('/'+ name));

QString parentdir = uploadPath + fajlovi.left(fajlovi.lastIndexOf('/'));
// ftp->cd(parentdir);
qDebug() << fajlovi << "is file and its parent dir is " << parentdir ;
ftp->cd(parentdir);
uploadFile(info.absoluteFilePath(), info.baseName());

}


}


}


Basically what uploadirectory function does is creates the dir of the main dir(i find the name of it in the top of code as described) inside ftp server, then i use qiterator to go trough every dir or file and if its dir i get its parent dir, ftp->cd inside of it then upload the file or just create dir if its dir.

The problem is this sometimes doesnt work because getting parent dir with this QString functions is as i experienced unreliable, what i really need is either fix that would make this work or another reliable way to handle uploading of entire dirs, please help me finally solve this, if anyone knows a source that explains how this is done maybe?

I am sick of this problem totally :(

ChrisW67
13th July 2010, 06:11
Any particular reason you didn't use a recursive approach? Something like:
void upload(const QString &localPath)
{
QFileInfo localInfo(localPath);
if (localInfo.isFile()) {
qDebug() << "FTP put file" << localInfo.fileName();
}
else if (localInfo.isDir()) {
qDebug() << "FTP mkdir" << localInfo.fileName();

QDirIterator it(localPath,
QDir::NoDotAndDotDot | QDir::Dirs | QDir::Files);
if (it.hasNext()) {
// only bother if there is something to do; the remote chdir() is expensive
qDebug() << "FTP cd" << localInfo.fileName();

while (it.hasNext()) {
QFileInfo info = it.next();
upload(info.absoluteFilePath());
}

qDebug() << "FTP cd ..";
}
}
}

called like:

qDebug() << "FTP cd remotepath";
upload("/tmp/main.cpp"); // will create remotepath/main.cpp file on remote

qDebug() << "FTP cd remotepath2";
upload("/tmp"); // will create a remotepath2/tmp folder tree on remote


You will need to insert the FTP commands, check for errors, test etc.

msimurin
13th July 2010, 06:30
Thank you ChrisW67 for taking time to help, i tried recursive approach before but i didnt do it right so i switched to this. I will try what you suggested now and see how it goes...

msimurin
13th July 2010, 18:01
Ok, after testing this it seems everything works solid and well, you saved me ChrisW67, there is just one small problem, it takes 45 minutes to upload bunch of files(total of 19mb) which is really slow for my upload connection. By watching netlimiter and monitoring upload speeds it seems it is always low speed for some reason, like from 3-20kB average or less. I can normally pull 50kB.

is there anything i could do about this?

ChrisW67
15th July 2010, 00:45
The network speed is unrelated to code for walking the directory tree. It will only try to send one file at a time and there will be almost no time between finishing a file upload and issuing the next FTP command. The speed onto the wire could be constrained by the FTP code you are using, external users of the link, firewalls, the remote end... Try sending the same set of files using another FTP client (e.g. FileZilla) to get an unbiased comparison figure.

Make sure the FTP connection is not reporting error or even being dropped/re-established for each file.