1 /*************************************************************************** 2 qgscopyfiletask.cpp 3 -------------------------------------- 4 Date : March 2021 5 Copyright : (C) 2021 by Julien Cabieces 6 Email : julien dot cabieces at oslandia dot com 7 *************************************************************************** 8 * * 9 * This program is free software; you can redistribute it and/or modify * 10 * it under the terms of the GNU General Public License as published by * 11 * the Free Software Foundation; either version 2 of the License, or * 12 * (at your option) any later version. * 13 * * 14 ***************************************************************************/ 15 16 #include "qgscopyfiletask.h" 17 18 #include <QFile> 19 #include <QFileInfo> 20 #include <QDir> 21 QgsCopyFileTask(const QString & source,const QString & destination)22QgsCopyFileTask::QgsCopyFileTask( const QString &source, const QString &destination ) 23 : mSource( source ), 24 mDestination( destination ) 25 { 26 } 27 run()28bool QgsCopyFileTask::run() 29 { 30 QFile fileSource( mSource ); 31 if ( !fileSource.exists() ) 32 { 33 mErrorString = tr( "Source file '%1' does not exist" ).arg( mSource ); 34 return false; 35 } 36 37 if ( QFileInfo( mDestination ).isDir() ) 38 { 39 mDestination = QDir( mDestination ).absoluteFilePath( QFileInfo( fileSource ).fileName() ); 40 } 41 42 QFile fileDestination( mDestination ); 43 if ( fileDestination.exists() ) 44 { 45 mErrorString = tr( "Destination file '%1' already exist" ).arg( mDestination ); 46 return false; 47 } 48 49 const QDir destinationDir = QFileInfo( mDestination ).absoluteDir(); 50 if ( !destinationDir.exists() ) 51 { 52 mErrorString = tr( "Destination directory '%1' does not exist" ).arg( destinationDir.absolutePath() ); 53 return false; 54 } 55 56 fileSource.open( QIODevice::ReadOnly ); 57 fileDestination.open( QIODevice::WriteOnly ); 58 59 const int size = fileSource.size(); 60 const int chunkSize = std::clamp( size / 100, 1024, 1024 * 1024 ); 61 62 int bytesRead = 0; 63 std::vector<char> data( chunkSize ); 64 while ( true ) 65 { 66 const int len = fileSource.read( data.data(), chunkSize ); 67 if ( len == -1 ) 68 { 69 mErrorString = tr( "Fail reading from '%1'" ).arg( mSource ); 70 return false; 71 } 72 73 // finish reading 74 if ( !len ) 75 break; 76 77 if ( fileDestination.write( data.data(), len ) != len ) 78 { 79 mErrorString = tr( "Fail writing to '%1'" ).arg( mDestination ); 80 return false; 81 } 82 83 bytesRead += len; 84 setProgress( static_cast<double>( bytesRead ) / size ); 85 } 86 87 setProgress( 100 ); 88 89 fileSource.close(); 90 fileDestination.close(); 91 92 return true; 93 } 94 errorString() const95const QString &QgsCopyFileTask::errorString() const 96 { 97 return mErrorString; 98 } 99 destination() const100const QString &QgsCopyFileTask::destination() const 101 { 102 return mDestination; 103 } 104