Partage
  • Partager sur Facebook
  • Partager sur Twitter

Copier coller un fichier avec un programme en c++

    3 janvier 2014 à 19:05:24

    Bonjour,

    j'aimerais savoir comment, depuis un programme en c++, on peut copier coller un executable et ses dll dans un endroit n'importe où, sur son ordi.

    merci de vos réponses

    • Partager sur Facebook
    • Partager sur Twitter

    Antoine

      3 janvier 2014 à 21:07:05

      Bonjour.

      Si tu veux copier un fichier déjà existant sur ton disque tu peux utiliser fstream. Documentation et le tutoriel sur la manipulation de fichier du site.

      • Partager sur Facebook
      • Partager sur Twitter
        4 janvier 2014 à 10:30:11

        Sur le tutoriel du site on ne parle que de la lecture et l'écriture dans un fichier texte
        • Partager sur Facebook
        • Partager sur Twitter

        Antoine

          4 janvier 2014 à 10:48:41

          Salut :)


          Si tu lis un fichier, tu le charge dans la memoire de ton programme, ce qui correspondrat, au copier ;)

          Ensuite, tu créer un fichier plus loin où tu veut, et ecris le contenue que tu avais charger dedans, ce qui correspondrais au coller ;)

          -
          Edité par Hackbug 4 janvier 2014 à 10:49:41

          • Partager sur Facebook
          • Partager sur Twitter
            4 janvier 2014 à 11:07:05

            Peut tu me montrer ce que ça donne dans un code source ?
            • Partager sur Facebook
            • Partager sur Twitter

            Antoine

              4 janvier 2014 à 11:47:29

              bien sur ;)

              Excuse moi du retard je m'etais absenté :/

              #include <iostream>
              #include <fstream>
              #include <string>
              
              using namespace std;
              
              int main(void)
              {
                  ifstream fichier("fichier.txt");  // Flux de lecture
                  ofstream flux("dossier/fichier.txt"); // Flux d'ecriture
              
                 if(fichier) // Si le fichier existe bien
                 {
                    string ligne;
              
                    while(getline(fichier, ligne)) // On le lis ligne par ligne
                    {
                          if(flux) // Si le lieu de destination existe ( j'entend par la le dossier )
                          {
                              flux << ligne << endl; // On ecrit dans le fichier de destination
                          }                          // Et au passage on le créer si il n'existe pas
                          else
                          {
                              cout << "ERREUR: Impossible d'ouvrir le fichier." << endl;
                          }
                    }
                 }
                 else
                 {
                    cout << "ERREUR: Impossible d'ouvrir le fichier en lecture." << endl;
                 }
              
                  return 0;
              }


              J'ai tester et sa marche :) après faut s'arranger pour pouvoir choisir les dossier et tout le reste, et c'est encore un autre soucis :p car le programme ne créer pas le sous dossier "dossier" mais il existe forcement un moyen pour y arriver ;)

              en tout cas j'espère que tu as compris l'idée :)

              Bon courage :)

              -
              Edité par Hackbug 4 janvier 2014 à 11:52:29

              • Partager sur Facebook
              • Partager sur Twitter
                4 janvier 2014 à 11:55:55

                Dans la doc ;)

                // Copie un fichier
                #include <fstream>      // ifstream, ofstream
                
                using namespace std;
                
                int main () {
                  ifstream infile ("test.png",ifstream::binary);
                  ofstream outfile ("new.png",ofstream::binary);
                
                  // Recupere la taille du fichier
                  infile.seekg(0,infile.end); // On se place a la fin du fichier
                  long size = infile.tellg(); // On recupere notre position
                  infile.seekg (0); // Et on se replace au debut du fichier
                
                  // On alloue de la memoire pour le contenue du fichier
                  char* buffer = new char[size];
                
                  // On lit le contenue du fichier
                  infile.read (buffer,size);
                
                  // On ecrit ce contenue dans le fichier a coller
                  outfile.write (buffer,size);
                
                  // Et on desalloue la memoire
                  delete[] buffer;
                
                  // Enfin on ferme les fichiers
                  outfile.close();
                  infile.close();
                  return 0;
                }
                

                J'ai testé ce code et il marche très bien :)

                 Edit : trop tard ^^

                Le code de la doc ne fais pas de vérifications par contre.

                -
                Edité par PowerFullKnight 4 janvier 2014 à 11:56:56

                • Partager sur Facebook
                • Partager sur Twitter
                  4 janvier 2014 à 11:59:23

                  C'est vraie que je n'avais pas regarder du coté de la doc pour trouver une solution, ni même pour connaitre un peu plus les fonction de <fstream> qui m'ont l'air ma foi fort interessante :)
                  • Partager sur Facebook
                  • Partager sur Twitter
                    4 janvier 2014 à 12:01:17

                    Oui, et cette technique a surement l'avantage d'être plus rapide vu qu'on ne lit et n'écrit qu'une seul fois dans les fichiers :)
                    • Partager sur Facebook
                    • Partager sur Twitter
                      4 janvier 2014 à 13:11:25

                      Cachez ces pointeurs nus que nous ne saurions voir. (Surtout quand un std::vector, est bien plus simple à utiliser ici).

                      -
                      Edité par Ksass`Peuk 4 janvier 2014 à 13:25:50

                      • Partager sur Facebook
                      • Partager sur Twitter

                      Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C

                        4 janvier 2014 à 13:20:44

                        Ok je testerais ça. Ça marche pour n'importe quel fichiers ?
                        • Partager sur Facebook
                        • Partager sur Twitter

                        Antoine

                          4 janvier 2014 à 14:21:33

                          Oui, normalement ca marche pour tout les fichiers, j'ai teste avec du png et ca marche bien.

                          Desole pour les pointeurs :o

                          • Partager sur Facebook
                          • Partager sur Twitter
                            4 janvier 2014 à 14:41:28

                            @PowerFullKnight: essaye voir sur de gros fichiers (genre plus de 16G, histoire de saturer la ram et le swap). Ou un device spécifique (genre /dev/stdin (mhouarf)). Je suis persuadé que 1) ton prog crash avec un bad_alloc, 2) il n'écrit rien ;).
                            Le plus sûr étant de lire/écrire par paquet en boucle. Avec un buffer de 4k par exemple (taille arbitraire).

                            #include <fstream>
                            
                            int main () {
                              std::ifstream infile("test.png", std::ios_base::binary);
                              std::ofstream outfile("new.png", std::ios_base::binary);
                            
                              if (!infile || !outfile) {
                                return 1;
                              }
                            
                              char buffer[4*1024];
                            
                              while (infile.read(buffer, sizeof(buffer))) {
                                if (!outfile.write(buffer, sizeof(buffer))) {
                                  return 2;
                                }
                              }
                            
                              if (!infile.eof()) {
                                return 3;
                              }
                            
                              //écrit les caractères restant du buffer
                              if (!outfile.write(buffer, infile.gcount())) {
                                return 2;
                              }
                            
                              return 0;
                            }


                            Mais sinon on peut se passer du buffer intermédiaire en allant un niveau en dessous: filebuf.

                            #include <fstream>
                            
                            int main () {
                              std::ofstream outfile("new.png", std::ios_base::binary);
                              std::filebuf infile;
                            
                              if (!outfile || !infile.open("test.png", std::ios_base::binary|std::ios_base::in)) {
                                return 1;
                              }
                            
                              typedef std::filebuf::traits_type traits;
                            
                              // si le fichier de lecture est vide, rien à faire (note: outfile << &infile avec un streambuf vide, set un badbid)
                              if (traits::eq_int_type(infile.sgetc(), traits::eof())) {
                                return 0;
                              }
                            
                              if (!(outfile << &infile)) {
                                return 3;
                              }
                            
                              if (infile.sgetc() != traits::eof()) {
                                return 2;
                              }
                            
                              return 0;
                            }



                            -
                            Edité par jo_link_noir 4 janvier 2014 à 15:07:57

                            • Partager sur Facebook
                            • Partager sur Twitter
                              4 janvier 2014 à 14:56:47

                              Je n'avais effectivement pas pensé a ça :)

                              -
                              Edité par PowerFullKnight 4 janvier 2014 à 16:05:45

                              • Partager sur Facebook
                              • Partager sur Twitter
                                4 janvier 2014 à 15:43:51

                                je testerai vos codes sources (je vais peut être vous poser d'autres questions parce que vous m'avez mis plusieurs codes et que je suis débutant en c++). Je voulais savoir aussi comment executer un executable a la manière des fichiers batch (start ...).
                                • Partager sur Facebook
                                • Partager sur Twitter

                                Antoine

                                  4 janvier 2014 à 15:57:31

                                  merci hackbug ton code fonctionne très bien merci. si je veux, avec ton même code source, copier 2 fichiers en même temps ça donne quoi ?
                                  • Partager sur Facebook
                                  • Partager sur Twitter

                                  Antoine

                                    6 janvier 2014 à 10:19:24

                                    Bonjour.

                                    Pour copier un fichier, tu peux faire à la main, comme proposé plus haut, ou utiliser boost filesystem.Si tu choisis cette dernière option, la doc est ici.

                                    http://www.boost.org/doc/libs/1_46_1/libs/filesystem/v3/doc/reference.html#copy_file

                                    Quelque soit l'option choisie, tu dois aussi tester que le fichier d'entrée soit différent du fichier de sortie. C'est pas forcément super évident, deux chemins différents (comme ./truc et ../machin/truc ) peuvent pointer vers le même fichier.

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      6 janvier 2014 à 23:48:45

                                      Ashitaka_AD a écrit:

                                      merci hackbug ton code fonctionne très bien merci. si je veux, avec ton même code source, copier 2 fichiers en même temps ça donne quoi ?


                                      Excellente question :p je n'en sais trop rien, il faudrait que je me penche un peu dessus pour y réfléchir ;)
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        7 janvier 2014 à 2:19:45

                                        Faire des copies parallèles est une fausse bonne idée, c'est le bon moyen de ralentir l'écriture. Surtout que le code de Hackbug à tous les éléments pour rendre la double copie catastrophique.

                                        Pour commencer, les copies de fichier se font généralement sur le même disque. Sollicité le disque de tous côté le ralentit considérablement. Le test est simple, combien de temps cela prend-t-il quand

                                        • Quelques fichiers de plusieurs giga sont copiés un par un (parallèle) dans des emplacements différents ?
                                        • Quelques fichiers de plusieurs giga sont copiés un après l'autre (fifo) dans des emplacements différents ? La première solution prendra à peu de chose près 2x fois plus de temps.

                                        Pourquoi le code de Hackbug est une catastrophe (sans vouloir vexé) ? Il fonctionne bien mais fait beaucoup de chose la où peu est demandé:

                                        • Utilisation de getline: engendre de l'allocation dynamique lié au std::string et lance un algorithme de recherche pour déterminer la fin d'une ligne. A-t-on besoin de manipuler des lignes ? Non, istream::write + tableau de taille fixe est préférable.
                                        • Utilisation intempestive de endl. Ou comment faire des copies dans un buffer et le vider immédiatement pour sollicité le disque. endl fait un saut de ligne + un flush. Le flush engendre un appel kernel et une opération d'écriture, deux choses réputées lourde. Le buffer existe pour minimiser les opérations de flush ; le flush doit être fait uniquement si il est nécessaire. Quant est-il nécessaire ? Quant l'écriture est terminée et donc à la fin de la boucle. Note que si le buffer est plein, un flush sera automatiquement fait.

                                        Sinon, pour copier des fichiers utilise le mode binaire (std::ios::binary). Windows à un comportement différent avec les fichiers texte et binaire et comme tu te fiches de lire le contenu du fichier, ouvre le en binaire. Par contre je me demande comment se comporte std::getline sur Windows avec un fichier ouvert en mode binaire ?

                                        -
                                        Edité par jo_link_noir 7 janvier 2014 à 2:21:35

                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          8 janvier 2014 à 13:56:50

                                          Merci m'aider parce que je suis débutant en c++. Il n'existe donc pas un code parfait ?
                                          • Partager sur Facebook
                                          • Partager sur Twitter

                                          Antoine

                                            8 janvier 2014 à 15:16:18

                                            Si tu veux un bon truc,je te conseille de déléguer le travail à une bibliothèque externe qui fera ça mieux que toi. Je te conseille boost::filesystem (c.f. mon post précédent). Si t'as pas besoin d'un truc portable, tu peux peut être utiliser une commande de ton OS avec system.

                                            • Partager sur Facebook
                                            • Partager sur Twitter

                                            Copier coller un fichier avec un programme en c++

                                            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                            • Editeur
                                            • Markdown