#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 car le programme ne créer pas le sous dossier "dossier" mais il existe forcement un moyen pour y arriver
// 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
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
@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
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 ...).
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.
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.
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 ?
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.
× 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.
Antoine
Antoine
Antoine
Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C
Antoine
Antoine
Antoine
* Un wrapper C++ pour sqlite * Une alternative a boost units
Antoine
* Un wrapper C++ pour sqlite * Une alternative a boost units