QGIS API Documentation  3.22.4-Białowieża (ce8e65e95e)
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 
22 QgsCopyFileTask::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 
95 const QString &QgsCopyFileTask::errorString() const
96 {
97  return mErrorString;
98 }
99 
100 const 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.