Datei binär kopieren


  • Mod

    Du musst die Datei schon in irgendeine Datenstruktur einlesen, die du dann in Pakete packst und verschickst. Ein char Array bietet sich für so etwas an.

    Pseudocode Server:

    Datei öffen;
    Schicke ein Signal an Client, dass es losgeht;
    So lange noch nicht Dateiende erreicht
     {
       Lese ein Stückchen der Datei in char Array;
       Verschicke char Array;
     }
    Schicke ein Signal an Client, dass fertig;
    

    Pseudocode Client:

    Wenn Signal zum loslegen empfangen{
     So lange bis Endsignal empfangen
      {
        Empfange Paket;
        Hänge Paketinhalt an Datei an;
      }
    


  • Ja, das klingt sinnvoll, jedoch war ich mir nicht sicher ob dies funktioniert.
    Kannst du mir sagen, wie ich ein einzelnes Zeichen (oder Zeichenblöcke) aus einer Datei kopieren kann?


  • Mod

    DerCoder schrieb:

    Kannst du mir sagen, wie ich ein einzelnes Zeichen (oder Zeichenblöcke) aus einer Datei kopieren kann?

    Entweder ist die Antwort trivial oder ich verstehe nicht, was du meinst. Weißt du etwa nicht wie man aus Dateien liest?



  • Doch doch, das weiß ich schon 😛 Nur frage ich mich ob es schnell genug ist, wenn ich eine Zeile aus der Datei auslese und sie komplett versende oder immer nur substrings...

    *edit*
    Okay es klappt 🙂 Ich war mir nicht sicher. Vielen Dank für deine Hilfe.

    *edit2*
    Lol, doch nicht.
    Ich benutze folgenden Code um die Datei Blockweise zu verschicken:

    ifstream fileIn("C:\\programmIn.exe", ios::binary);
        while (!fileIn.eof ())
        {
            string stringFileBuffer ("");
            char buffer[64];
            fileIn.read (buffer, sizeof(buffer));
            stringFileBuffer = buffer;
            MyMessObj.SendMessagePort (stringFileBuffer);
        }
    	fileIn.close ();
    

    und zum empfangen:

    // im header bereich:
    ofstream fileOut ("C:\\programmOut.exe", ios::trunc | ios::binary);
    // im rec thread:
        char temp[4096];
    	int iStat;
    
    	iStat = recv (sRecSocket, temp, sizeof (temp), 0);
    	if (iStat == -1)
    	{
    		m_vClientList.remove (sRecSocket);
    		return 1;
    	}
    	else
    	{
               string InputMessage (temp);
               fileOut.write (InputMessage.c_str (), sizeof(InputMessage.c_str ()));
               fileOut.flush ();
            }
    // programm ende:
    fileOut.close ();
    

    Die erstellte Datei ist allerdings nur 1KB groß.



  • Der Fehler liegt bei dir in der Umwandlung von char* nach string: der Konstruktor string(char 😉 erwartet einen null-terminierten C-String!!!

    Und der zweite Fehler: der Rückgabewert von 'recv' gibt die Anzahl der gelesenen Bytes an, d.h. kopiere die Daten direkt:

    int count = recv(...);
    if(count >= 0)
    {
      fileOut.write (temp, count);
    }
    

    Edit: Tippfehler...

    P.S. habe gerade noch deinen 3. Fehler entdeckt: sizeof(InputMessage.c_str ())
    Überleg mal, welcher (konstante) Wert da raus kommt...



  • Arg. Ist mir nichtmal aufgefallen.
    Die Datei kommt allerdings immernoch nicht komplett an:

    iStat = recv (sRecSocket, temp, 4096, 0);
    	if (iStat >= 0)
    	{
            fileOut.write (temp, iStat);
            fileOut.flush ();
            }
    


  • Du hast beim Senden den selben Fehler drin (char * -> string)!!!



  • Hilft auch nicht wirklich ...

    *edit*
    Ich hab jetzt anstatt

    fileOut.write (temp, iStat);
    
    fileOut.write (temp, 64);
    

    ausprobiert. Die Datei kommt jetzt sogar noch größer an, als die Quelledatei ist.



  • Ich schrieb: Senden !!!

    stringFileBuffer = buffer;
    MyMessObj.SendMessagePort (stringFileBuffer);
    

    Ändere deine Methode SendMessagePort so ab, daß sie einen char-Zeiger und eine Größe erhält, also:

    MyMessObj.SendMessagePort (buffer, fileIn.gcount());
    

    Vllt. solltest du dich ersteinmal mit den Unterschieden zwischen ASCII und Binär sowie std::string und C-Strings auseinandersetzen, um auch den Code zu verstehen...



  • Hmm okay. Das hatte ich nicht bedacht. Vielen Dank für deine Geduld.


Anmelden zum Antworten