2010-09-29 18 views
3

J'utilise le programme suivant pour essayer de copier le contenu d'un fichier, src, vers un autre, dest, en C++. Le code simplifié est donné ci-dessous:Copie du contenu d'un fichier dans un autre en C++

#include <fstream> 
using namespace std; 
int main() 
{ 
    fstream src("c:\\tplat\test\\secClassMf19.txt", fstream::binary); 
    ofstream dest("c:\\tplat\\test\\mf19b.txt", fstream::trunc|fstream::binary); 
    dest << src.rdbuf(); 
    return 0; 
} 

Quand je construit et exécuté le programme en utilisant codeblocks avec GCC ide compilateur dans les fenêtres, un nouveau fichier nommé « .... mf19.txt » a été créé, mais aucune donnée était copié dedans, et filesize = 0kb. Je suis certain que j'ai des données dans "... secClassMf19.txt".

j'éprouve le même problème quand je compilé le même progeam dans les fenêtres Visual C++ 2008.

Quelqu'un peut-il s'il vous plaît aider à expliquer pourquoi je reçois ce comportement inattendu, et plus important encore, comment résoudre le problème?

+0

Bienvenue sur stackoverflow.com. La prochaine fois, Pelase formatera votre code en utilisant le bouton '101010' situé en haut de la fenêtre d'édition. En outre, vous pouvez lire la [FAQ] (http://stackoverflow.com/faq). – sbi

+0

Quand vous dites que vous êtes sûr que vous avez des données dans secClassMf19.txt, l'avez-vous réellement ouvert dans le Bloc-notes et jeté un coup d'oeil? –

Répondre

4

Vous devez vérifier si l'ouverture des fichiers réussit réellement avant d'utiliser ces flux. En outre, il ne fait jamais mal de vérifier si tout s'est bien passé après. Changez votre code à ceci et rapportez-vous:

int main() 
{ 
    std::fstream src("c:\\tplat\test\\secClassMf19.txt", std::ios::binary); 
    if(!src.good()) 
    { 
     std::cerr << "error opening input file\n"; 
     std::exit(1); 
    } 
    std::ofstream dest("c:\\tplat\\test\\mf19b.txt", std::ios::trunc|std::ios::binary); 
    if(!dest.good()) 
    { 
     std::cerr << "error opening output file\n"; 
     std::exit(2); 
    } 
    dest << src.rdbuf(); 
    if(!src.eof()) 
     std::cerr << "reading from file failed\n"; 
    if(!dst.good()) 
     std::cerr << "writing to file failed\n"; 
    return 0; 
} 

Je parie que vous rapporterez que l'un des deux premiers contrôles vérifie.

Si l'ouverture du fichier d'entrée échoue, essayez de l'ouvrir en utilisant std::ios::in|std::ios::binary au lieu de simplement std::ios::binary.

1

Avez-vous des raisons de ne pas utiliser la fonction CopyFile?

Meilleur

+0

J'ai essayé les suggestions de sbi (en utilisant std :: ios :: in | std :: ios :: binary au lieu de simplement std :: ios :: binary), toujours le programme ne parvient pas à lire le fichier d'entrée (return 1) . Même en utilisant ifstream comme suggéré par gavinb yiels pas de joie. –

+0

Je viens de voir la suggestion de Vagaus par. Copier un fichier. Mais j'ai essayé cela plus tôt (en ajoutant #include Le code que j'ai utilisé alors était: CopyFile ((LPCWSTR) "c: \\ tplat \ test \\ secClassMf19.txt", (LPCWSTR) "c: \\ tplat \\ test \\ mf19b.txt ", true); Mais cela n'a pas fonctionné non plus Peut-être que je fais quelque chose de mal –

1

Comme il est écrit, votre instance src est une fstream régulière, et vous ne spécifiez pas un mode ouvert pour l'entrée. La solution simple est de faire src une instance de ifstream, et votre code fonctionne. (Juste en ajoutant un octet!)

Si vous aviez testé le flux d'entrée (comme le suggère sbi), vous auriez trouvé qu'il n'était pas ouvert correctement, c'est pourquoi votre fichier de destination était de taille nulle. Il a été ouvert en mode écriture (puisqu'il s'agissait d'un ofstream) avec l'option de troncature pour le rendre nul, mais l'écriture du résultat de rdbuf() a simplement échoué, sans rien écrire.

Une autre chose à noter est que, bien que cela fonctionne bien pour les petits fichiers, il serait très inefficace pour les fichiers volumineux. En l'état, vous lisez en mémoire le contenu entier du fichier source, puis vous l'écrivez à nouveau dans un grand bloc. Cela gaspille beaucoup de mémoire. Il vaut mieux lire en morceaux (disons 1 Mo par exemple, une taille raisonnable pour un cache disque) et écrire un morceau à la fois, le dernier étant le reste de la taille. Pour déterminer la taille de la source, vous pouvez rechercher jusqu'à la fin et interroger le décalage de fichier, puis vous savez combien d'octets vous traitez.

Et vous trouverez probablement que votre système d'exploitation est encore plus efficace pour copier des fichiers si vous utilisez les API natives, mais cela devient moins portable. Vous voudrez peut-être regarder le module de système de fichiers Boost pour une solution portable.

+0

J'ai essayé la suggestion de sbi, et il montre l'erreur en lisant le fichier d'entrée (retuen 1). –

+0

J'ai essayé les suggestions de sbi (en utilisant std :: ios :: in | std :: ios :: binary au lieu de simplement std :: ios :: binary), toujours le programme ne parvient pas à lire le fichier d'entrée (return 1) Même en utilisant ifstream comme suggéré par gavinb yiels aucune joie Je viens de voir la suggestion de Vagaus par CopyFile Mais j'ai essayé cela plus tôt (en ajoutant #include Le code que j'ai utilisé était alors: CopyFile ((LPCWSTR) "c: \ \ tplat \ test \\ secClassMf19.txt ", (LPCWSTR)" c: \\ tplat \\ test \\ mf19b.txt ", true); Mais cela n'a pas fonctionné non plus et le fichier s'ouvre dans NOTEPAD, la taille est seulement 1kb. –

+0

@T J: Echoue-t-il à _open_ le fichier ou échoue-t-il à _read_ it? – sbi

Questions connexes