QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
qgscopyfiletask.cpp
Go to the documentation of this file.
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
22QgsCopyFileTask::QgsCopyFileTask( const QString &source, const QString &destination )
23 : mSource( source ),
24 mDestination( destination )
25{
26}
27
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
95const QString &QgsCopyFileTask::errorString() const
96{
97 return mErrorString;
98}
99
100const QString &QgsCopyFileTask::destination() const
101{
102 return mDestination;
103}
const QString & destination() const
It could be different from the original one.
bool run() override
Performs the task's operation.
const QString & errorString() const
Returns errorString if an error occurred, else returns null QString.
QgsCopyFileTask(const QString &source, const QString &destination)
Creates a task that copy source file to destination.
void setProgress(double progress)
Sets the task's current progress.