Exe kopieren



  • Habe mir überlegt, dass durch auslesen einer Exe-Datei in einen Vektor und anschließendes Ausgeben des Vektors in einen Stream eine Exe kopiert werden könnte.
    Habe folgenden Code geschrieben:

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <vector>
    #include <iterator>
    using namespace std;
    int main(void)
    {
       string dateiname = "Test.exe";
       string target = "Ziel.exe";
       vector<int> lese;
       fstream hallo(dateiname.c_str(),ios::in | ios::binary);   
       while(!hallo.eof())
       {
          lese.push_back(hallo.get());
       }
       hallo.close();
       hallo.open(target.c_str(),ios::out | ios::binary);
       ostream_iterator<int> in(hallo);
       vector<int>::iterator start = lese.begin();
       vector<int>::iterator ende = lese.end();   
       while(start != ende)   //Vektor und gleichzeitig Zeiger auf 'hallo' wird durchlaufen und geschrieben.
       {
          *in++ = *start++;          
       }
       system("Pause");   
    }
    

    Doch die Exe-Datei bleibt leer.
    Wird zwar erstellt: Bleibt aber leer 😞

    cya
    David



  • Du weißt nicht wirklich, was du da machst, oder? 😛 Der einfachste Weg ist sicherlich:

    #include <fstream>
    #include <iostream>
    
    int main()
    {
        std::ifstream file_stream_in("test.txt");  
        if (!file_stream_in) { std::cerr << "FEHLER: \"test.txt\" nicht gefunden!" << std::endl; return 1; }
    
        std::ofstream file_stream_out("output.exe");
        file_stream_out << file_stream_in.rdbuf();
    }
    

    Und jetzt deinen Weg:

    #include <fstream>
    #include <iostream>
    #include <iterator>
    #include <vector>
    #include <algorithm>
    
    int main()
    {
        std::ifstream file_stream_in("test.txt");  
        if (!file_stream_in) { std::cerr << "FEHLER: \"test.txt\" nicht gefunden!" << std::endl; return 1; }
        std::vector<unsigned char> file_data(std::istream_iterator<unsigned char>(file_stream_in), std::istream_iterator<unsigned char>());
    
        std::ofstream file_stream_out("output.exe");
        std::copy(file_data.begin(), file_data.end(), std::ostream_iterator<unsigned char>(file_stream_out));
    }
    

    ...



  • Erstens: Wenn du die Daten über einen ostream_iterator schreibst, nutzt der den operator<< für die Ausgaben - d.h. du bekommst dort eine Aneinanderreihung von Zahlen, mit der niemand etwas anfangen kann (mangels Trennzeichen nichtmal du).
    Du mußt schon mit char-Daten und einem ostreambuf_iterator arbeiten (oder, da du sowieso von Hand kopierst, den Stream-Iterator weglassen und alle Ausgaben mit put() schreiben).

    Zweitens: Am Ende der Einlesen-Schleife sind eofbit und failbit deines Streams gesetzt - und werden auch durch das Schließen und neu Öffnen des Streams nicht wieder zurückgesetzt. In dem Zustand verweigert der Stream aber die Zusammenarbeit, darum mußt du die Fehlerflags noch mit "hallo.clear();" zurücksetzen.

    Drittens: Warum so umständlich?

    ifstream src(dateiname.c_str(),ios::in|ios::binary);
    ofstream tgt(target.c_str(),ios::out|ios::binary);
    tgt<<src.rdbuf();
    


  • Thx
    CStoll's und (D) Evils (!!!^^) Lösung funktioniert.
    Nur 3 Zeilen - ist echt unglaublich^^
    Muss mich mal noch drüber informieren, was rdbuf() und ostreambuf genau ist.



  • Tjo hatte ich ja auch schon vorher auch gepostet 😛



  • Oh ... hehe.
    Mir ist noch ne Frage eingefallen.
    Die Operatoren << und >> lesen oder schreiben doch nur bis zu einer Leerstelle.
    Warum funktioniert eure Version trotzdem?
    Weil in jeder Datei kann ja mal ne Leerstelle vorkommen, oder?

    cya
    David



  • ? Warum sollten die denn nur bis dahin schreiben?

    Also bsw. std::cin hat standardmäßig http://www.cplusplus.com/reference/iostream/manipulators/skipws.html aktiviert ... kannst du aber per http://www.cplusplus.com/reference/iostream/manipulators/noskipws.html aussschalten.

    Naja das ist aber nicht der Grund warum das funktioniert 😛 Also, es handelt sich ja bei std::fstream um einen gepufferten Lesestrom. Nun geht man per std::ifstream::rdbuf einfach hin und übergibt diesen Buffer des Lesestroms einfach an den Ausgabestrom!


Anmelden zum Antworten