Mourad2009B
Messages postés108Date d'inscriptionlundi 23 août 2010StatutMembreDernière intervention28 octobre 2024
-
16 févr. 2017 à 17:30
Nessdarth
Messages postés36Date d'inscriptionvendredi 16 décembre 2016StatutMembreDernière intervention28 février 2017
-
21 févr. 2017 à 21:01
Bonjour à tous,
J’essaye de créer une application qui me permet de sauvegarder un fichier ou un répertoire d’origine vers un répertoire de destination.
Le problème c’est que quand le processus de copie commence, la fenêtre de l’application devient bloquante, c’est-à-dire que je ne peux même pas la réduire ou la fermée e avant que la copie ne soit terminée.
Pour cela j’ai pensé à utiliser les threads, alors j’ai procédé comme suit :
J’ai créé la fonction suivante :
Remarques : j’ai remplacé une partie du code par des points, afin de réduire la taille du message)
qDebug() << "je suis bien dans la fonction copyDirFile"; replace(sourceFolderString.begin(), sourceFolderString.end(), '/','\\'); replace(destFolderString.begin(), destFolderString.end(), '/','\\');
//****************************************** //Si c'est un fichier FILE* sourceFile = fopen(sourceFolder, "rb"); if(sourceFile != NULL) { //On recupère le nom de fichier, on convertit de char a string pour pouvoir faire des manipulations string baseNameFile = sourceFolder; baseNameFile = baseNameFile.substr(baseNameFile.find_last_of("\\")+1, baseNameFile.size()); //On crée le fichier final de déstination …………………….. ………………………………………
} //Si ce n'est pas un fichier else { //On doit tester pour savoir si c'est un répertoire, on essayant de l'ouvrir DIR *dir = opendir(sourceFolder); struct dirent *ent; //Si l'ouverture s'est bien déroulée, donc c'est un répertoire if(dir != NULL) { //On récupère la base du nom du répertoire d'origine pour l'utiliser à créer le répertoire de destination. ………………………………………. //On met le curseur en position 2 pour éviter le (.) et les (..) des répertoires actuel et précédent. seekdir(dir,2) ; //On liste tous les élément contenus dans le répertoire while ((ent = readdir (dir)) != NULL) { //On forme le fichier ou le repertoire de déstination, tout dépend de l'élément qu'on va lire ……………………………………………. //On ouvre le fichier FILE* fichier = fopen(actualFolderSource, "rb"); ARG_COPY_FILE Copy_file_struct = { Copy_file_struct.source = actualFolderSource, Copy_file_struct.destination = destFolderComplet, //Copy_file_struct.mutex = PTHREAD_MUTEX_INITIALIZER, }; //Si c'est un fichier if(fichier != NULL) { //*source = sourceFolder; *dest = destFolderComplet; Maj_struct_local.source = actualFolderSource; Maj_struct_local.destination = destFolderComplet;
fclose(fichier); } //Si ce n'est pas un fichier donc c'est surement un réperoire, on appelle donc récursivement la même fonction else copyDirFile(actualFolderSource, fullNameDirDest, Info_struct_local); } } //Ce n'esi pas un fichier et ce n'est pas un répertoire else return 3; } //Si on arrive jusqu'ici, cest que tout est bien passer return 0; }
Et voici la fonction copyFile :
void *copyFile(void *arguments) { qDebug() << "je suis bien dans la fonction copyFile"; qDebug() << "temoin = " << TEMOIN; ARG_COPY_FILE *args = (ARG_COPY_FILE *)arguments; //On définit les fichiers sources et déstination FILE* fSrc; FILE* fDest; char buffer[1024]; int NbLus; //On ouvre le fichier source if ((fsrc=""open(args->source, "rb")) == NULL) { //On retourne 1 pour dire que le fichier source n'a pas était ouvert. pthread_exit(NULL); } //On ouvre le fichier destination if ((fDest = fopen(args->destination, "wb")) == NULL) { //On ferme le fichier source fclose(fSrc); //On retourne 2 pour dire que le fichier de déstination n'a pas était ouvert pthread_exit(NULL); }
//Si tout se passe bien on lit les données du fichier source et on les enregistre dans le fichier de déstination while ((NbLus = fread(buffer, 1, 1024, fSrc)) != 0) fwrite(buffer, 1, NbLus, fDest);
//On ferme les deux fichier fclose(fDest); fclose(fSrc);
Info_struct_local.textEdit->append("copie de " + QString::fromStdString(Maj_struct_local.source) + " vers " + QString::fromStdString(Maj_struct_local.destination)); //Info_struct_local.textEdit->update(); Info_struct_local.progressBarre->setValue(Info_struct_local.progressBarre->value()+1); //On retourne 0 pour dire que tout c'est bien passé pthread_exit(NULL); }
Le problème c’est que la fenêtre est toujours bloquante.
Et c’est pour cela que j’ai besoin de vos lumières
Merci d’avance pour votre aide.
Nessdarth
Messages postés36Date d'inscriptionvendredi 16 décembre 2016StatutMembreDernière intervention28 février 20173 17 févr. 2017 à 10:06
Bonjour,
copyDirFile n'est pas dans un thread ?
Mourad2009B
Messages postés108Date d'inscriptionlundi 23 août 2010StatutMembreDernière intervention28 octobre 2024 17 févr. 2017 à 17:35
Bonjour Nessdarth et merci de prendre le temps de me répondre.
Oui effectivement copyDirFile n'est pas dans un thread, parce que comme c'est une fonction récursive j'ai pensé que ce n'est pas une bonne idée de la mettre dans un thread. à moins que tu as une autre idée à me proposée.
et merci encore
Nessdarth
Messages postés36Date d'inscriptionvendredi 16 décembre 2016StatutMembreDernière intervention28 février 20173
>
Mourad2009B
Messages postés108Date d'inscriptionlundi 23 août 2010StatutMembreDernière intervention28 octobre 2024 17 févr. 2017 à 19:25
Justement, c'est copyDirFile qui prendra le plus de charge il me semble, donc autant que cette lourde charge s'exécute dans un thread,et si j'ai bien lu, avec le code actuel, tu vas créer n threads, alors que si tu exécutes la 1ere occurrence de copyDirFile, toutes les autres occurrences se feront dans ce seul et même thread.
Mourad2009B
Messages postés108Date d'inscriptionlundi 23 août 2010StatutMembreDernière intervention28 octobre 2024 21 févr. 2017 à 16:29
Bonjour à tous,
Je vous remercie pour les conseils et les suggestions que vous avez voulu m’en faire profiter.
Après plusieurs modifications, je me suis résigné à utiliser
QCoreApplication::processEvents();
Car je crois que les thread ne sont pas adaptés à ma structure de code, vue que je vais modifier les valeurs d’un QProgressBar et le contenu d’un QTextEdit, et comme les thread ne permettent pas de communiquer avec les objets de l’interface graphique, donc j’ai choisi de rester dépéndant de Qt et d’utilisé
QCoreApplication::processEvents(); dans la boucle while de la fonction copyFile.
Et avec ça j’arrive à interagir avec mon interface graphique pendant le processus de copie.
En tout cas merci encore pour vos réponses
Nessdarth
Messages postés36Date d'inscriptionvendredi 16 décembre 2016StatutMembreDernière intervention28 février 20173
>
Mourad2009B
Messages postés108Date d'inscriptionlundi 23 août 2010StatutMembreDernière intervention28 octobre 2024 21 févr. 2017 à 16:37
Sinon pour info, tu peux communiquer vers le thread principal qui peut recevoir des messages du thread secondaire.
En utilisant un postMessage, par exemple, qui sera capté par le thread principal (celui qui gère l'interface graphique).
Par contre je ne connais pas l'équivalent de la fonction PostMessage pour Qt
Mourad2009B
Messages postés108Date d'inscriptionlundi 23 août 2010StatutMembreDernière intervention28 octobre 2024 21 févr. 2017 à 17:02
merci Nessdarth, je vais continuer à chercher une solution avec les thread, mais pour l'instant je vais finaliser mon programme avec Qt, pour pouvoir l'utilisé.
17 févr. 2017 à 17:35
Oui effectivement copyDirFile n'est pas dans un thread, parce que comme c'est une fonction récursive j'ai pensé que ce n'est pas une bonne idée de la mettre dans un thread. à moins que tu as une autre idée à me proposée.
et merci encore
17 févr. 2017 à 19:25
21 févr. 2017 à 16:29
Je vous remercie pour les conseils et les suggestions que vous avez voulu m’en faire profiter.
Après plusieurs modifications, je me suis résigné à utiliser
Car je crois que les thread ne sont pas adaptés à ma structure de code, vue que je vais modifier les valeurs d’un QProgressBar et le contenu d’un QTextEdit, et comme les thread ne permettent pas de communiquer avec les objets de l’interface graphique, donc j’ai choisi de rester dépéndant de Qt et d’utilisé
QCoreApplication::processEvents(); dans la boucle while de la fonction copyFile.
Et avec ça j’arrive à interagir avec mon interface graphique pendant le processus de copie.
En tout cas merci encore pour vos réponses
21 févr. 2017 à 16:37
En utilisant un postMessage, par exemple, qui sera capté par le thread principal (celui qui gère l'interface graphique).
Par contre je ne connais pas l'équivalent de la fonction PostMessage pour Qt
21 févr. 2017 à 17:02