Große Datei kopieren



  • cpy schrieb:

    @ Ethon nein so hatte ich es nicht.^^

    ( 1402197877 = Die Größe meiner Datei )

    copy_file<1402197877>(foo, bar);
    

    Aber mit 1024*1024*1024 geht es, aber warum geht es dann das hab ich noch nicht verstanden. Was macht der PC da intern anderes als wenn ich direkt die volle größe Schreibe?

    Die gcount Funktion gefällt mir die löst ja schonmal ein Problem von mir.^^ (Die kannte ich noch gar nicht.)

    Das ist das Problem, du machst den Puffer so groß wie die Datei, aber das geht schlecht. Nimm doch ein konservatives Vielfaches von 4096.

    copy_file<4096>(foo, bar);
    

    Der Code wird dann so oft (maximal) 4096 Byte große Häppchen kopieren, bis die Datei durch ist.



  • Es gibt da noch boost::filesystem::copy_file .



  • @Ethon ich hab es jetzt mal versucht aber mit einer etwas kleineren Datei ( 625.987.585 Bytes )

    Beim kopieren ist 1 Byte verloren gegangen o_O die neue Datei enthält nur 625.987.584 Bytes wie kann das sein?

    #include <iostream>
    #include <fstream>
    #include <vector>
    
    using namespace std;
    
    template <std::size_t BufSize> 
    void copy_file(std::istream& in, std::ofstream& out)
     {
       std::vector<char> buf(BufSize);
       while (in.read(&buf[0], buf.size()))
         out.write(&buf[0], in.gcount());
     }
    
    int main()
    {
    ifstream file ("dbg.txt",ios::binary);
    ofstream f ("Kopie von dbg.txt",ios::binary);
    
    copy_file<4096>(file, f);
    
    return 0;
    }
    


  • Ich hab jetzt auch nochmal mit einer kleinen Datei probiert ( 9 MB Datei )
    Da passiert das selbe es fehlt immer 1 Byte in der neuen Datei.

    Wenn ich jedoch immer Byte für Byte schriebe dann geht es.



  • Hab den Fehler gefunden es lag an der Kopfgesteuerten Schleife:

    So funktioniert es:

    template <std::size_t BufSize>
    void copy_file(std::istream& in, std::ofstream& out)
     {
       std::vector<char> buf(BufSize);
    
            do
            {
               in.read(&buf[0],BufSize);
               out.write(&buf[0],in.gcount() );
            }
            while( ! in.eof() );
     }
    


  • cpy schrieb:

    @ Tachyon

    In was für eine Block Größe schreibt rdbuf() ? Wobei eigentlich schreibt es ja nicht sondern gibt ein Stream Puffer Objekt was mit dem Stream verbunden ist zurück.
    So steht es zumindest dort -> http://www.cplusplus.com/reference/iostream/ios/rdbuf/

    std::ifstream reader(argv[1], std::ios::in|std::ios::binary);
    char buff[4096];
    reader.rdbuf()->pubsetbuf(buff, sizeof(buff));
    

    Und was Du tust ist auch nichts anderes als einen selbst gebastelten Puffer zu schreiben.


  • Mod

    cpy schrieb:

    Hab den Fehler gefunden es lag an der Kopfgesteuerten Schleife:

    Dann kopier mal eine Datei ohne Inhalt.

    Der Fehler lag garantiert in der üblichen Fehllogik aus schlechten Büchern.

    while(Leseaktion) Verarbeiten;  // richtig: Lesen, Bei Fehler abbrechen, richtige Daten verarbeiten
    
    while(!eof()) {Leseaktion; Verarbeiten;} // falsch: Bei Lesefehler(Dateiende) wird trotzdem was verarbeitet -> letzte Aktion doppelt
    


  • Na ja, da die Größe ja mit übergeben wird (und die dann 0 ist), sollte das kein Problem sein.



  • Bei einer Datei ohne Inhalt treten keine Probleme auf aber ich weiss jetzt was das Problem bei der anderen Lösung ist.

    template <std::size_t BufSize>
    void copy_file(std::istream& in, std::ostream& out)
     {
       std::vector<char> buf(BufSize);
       while ( in.read(&buf[0], buf.size()) ) // Irgendwann kommt das EOF
                                              // und dann wird die letzte write 
                                              // Operation übersprungen ...
       {
    	out.write(&buf[0], in.gcount() );
       }
    
       out.write(&buf[0], in.gcount() );  // Wenn hier nochmal write aufrufe dann 
                                          // funktioniert es
    
     }
    

    Ich glaub ich schau nachher nochmal in das Stroustroup bin ja jetzt zuhause.


  • Mod

    Ok, ich kannte den Code nicht, ich bin mal instinktiv von dem typischen Schlechtes-Lehrbuch-Pfusch ausgegangen, der hier 10x die Woche kommt. Im Stroustrup sollte es richtig erklärt sein.


Anmelden zum Antworten