PDA

View Full Version : Copy a File over the Network



raphaelf
16th June 2008, 16:23
Hi everybody,

i am trying to copy a File over the Network and i would like to show in a progressbar the status of copy..

I have tried this example but it takes to long.

i heard about QUrlOperator, but under QT 4 its not working..

Could somebody show me how to copy a big file over the network and show the status in a progressbar?



QFile src("W:\\1Data\\Public\\Transfer\\Notes.exe");
QFile dst("notes.exe");
if(!src.open(QFile::ReadOnly) || !dst.open(QFile::WriteOnly)) return;

qint64 len = src.bytesAvailable();
ui.dlg->setRange(0,len);
ui.dlg->show();
char ch;
while(!src.atEnd()){
src.getChar(&ch);
dst.putChar(ch);
ui.dlg->setValue(ui.dlg->value()+1);
qApp->processEvents();}

Thanks :o

marcel
16th June 2008, 19:40
It is slow because you're copying byte by byte... What if the file is 1Mb in size?
Try using QDataStream::readRawData and QDataSteam::writeBytes to read and write bigger chunks.

raphaelf
17th June 2008, 10:21
Hi,

Data between 50-300 MB :o

I search here and in the docs a example but i didint find it :crying:

Could somebody help me to use my code, but for big files? :crying:

Fastman
17th June 2008, 10:59
If use Windows - fastest metod:



qint16 nRet = CopyFileEx(source.utf16(), destination.utf16(), CopyProgressRoutine, (LPVOID)this, false, COPY_FILE_RESTARTABLE);


CallBack :



static DWORD WINAPI CopyProgressRoutine(LARGE_INTEGER TotalFileSize,
LARGE_INTEGER TotalBytesTransferred,
LARGE_INTEGER StreamSize,
LARGE_INTEGER StreamBytesTransferred,
DWORD dwStreamNumber,
DWORD dwCallbackReason,
HANDLE hSourceFile,
HANDLE hDestinationFile,
LPVOID lpData )
{
CWorkFiles &progressInfo = *(CWorkFiles *)lpData;
qint16 nPrc = (int)((TotalBytesTransferred.QuadPart * 100) / TotalFileSize.QuadPart);

if ((nPrc - progressInfo.nPrc_old) >= 5)
{
//For Example: write copy progress in database
//db_work db;
//db.SetPercent(nPrc, progressInfo.nId);
//db.CloseDB();
//progressInfo.nPrc_old = nPrc;
}

return PROGRESS_CONTINUE;
}


if you can use only QT:



bool CWorkFiles::copyFile (QString source, QString &destination, bool overwrite, bool move,qint16 nSysID)
{
db_work db;

QFileInfo sourceInfo = QFileInfo(source);
QFileInfo destinationInfo = QFileInfo(destination);

if(!sourceInfo.exists())
{
qDebug("File Copy Failed - Source File does not exists.");
return false;
}
else if(!sourceInfo.isFile())
{
qDebug("File Copy Failed - Source is not a file.");
return false;
}
else if(!destinationInfo.exists())
{
qDebug("File Copy Failed - Destination cannot be found.");
return false;
}

if(destinationInfo.isDir())
destination = (QFileInfo(QDir(destinationInfo.absoluteFilePath() ), sourceInfo.fileName())).filePath();
else if(!destinationInfo.isFile())
{
qDebug("File Copy failed - Destination is neither a file or directory.");
return false;
}

if(!overwrite && QFile::exists(destination))
{
qDebug("File Copy failed - Destination file exists, overwrite disabled.");
return false;
}

QFile sourceFile(source);
QFile destinationFile(destination);

if(sourceFile.open(QIODevice::ReadOnly) && destinationFile.open(QIODevice::WriteOnly))
{
// show progress
double nPercent = 0.00;
double nNewPercent = 0.00;
uint dataLength = 32 * 1024;
char *data = new char[dataLength];
double completed = 0;
double nFsize;
nFsize = sourceFile.size();
double dMn;

if (nFsize > 0)
{
db.SetPercent(0, nSysID);
db.CloseDB();
dMn = (100 / nFsize);
qint16 nCount = 0;
while(!sourceFile.atEnd())
{
qint64 nReaded = sourceFile.read(data, dataLength);
if (nReaded <= 0)
continue;
completed += nReaded;
destinationFile.write(data, nReaded);
destinationFile.flush();
nNewPercent = nPercent;
nCount++;

if (nCount > 100 || dataLength !=nReaded)
{
nPercent = completed * dMn;
db.SetPercent((qint64)nPercent, nSysID);
db.CloseDB();
nCount = 0;
}
}
}
else
{
delete[] data;
return false;
}
delete[] data;

db.SetPercent(100, nSysID);
db.CloseDB();

if(move)
{
if(!sourceFile.remove())
{
destinationFile.remove();
sourceFile.close();
destinationFile.close();
qDebug("File Copy failed - Source file could not be removed.");
return false;
}
}
sourceFile.close();
destinationFile.close();
}
else
{
sourceFile.close();
destinationFile.close();
qDebug("DBG: Error - Source or destination file could not be opened.");
qDebug("File Copy failed - Source or destination file could not be opened.");
return false;
}
return true;
}


For Windiws i'am use first example, because the sizes of files with which I work 1-15Gb the second example too works not bad - but more slowly.

raphaelf
17th June 2008, 13:36
Hi,

Thank you very much, it works :=)