Problem mit Funktion



  • Hi, ich hab n Problem mit ner Funktion, die eine Datei kopiert :

    file_from=fopen(from,"r");
    if(file_from==NULL)
    {
        MessageBox(hWnd,"File doesn't exist","Error",MB_ICONWARNING | MB_OK);
        return -1;
    }
    
    file_to  =fopen(to  ,"w");
    if(file_to==NULL)
    {
        MessageBox(hWnd,"Can't create file","Error",MB_ICONWARNING | MB_OK);
        return -1;
    }
    
    int size;
    int actual_size;
    
    bool end=0;
    
    fseek(file_from, 0, SEEK_END);
    size=ftell(file_from);
    
    fseek(file_from, 0, SEEK_SET);
    
    while(!end)
    {
        if((unsigned)(size-ftell(file_from))>memory_size)
        {
            actual_size=memory_size;
        }
        else
        {
            actual_size=size-ftell(file_from);
    
            end=1;
        }
    
        fread((void*)memory,1,actual_size,file_from);
    
        fwrite((void*)memory,1,actual_size,file_to);
    }
    
    fclose(file_from);
    fclose(file_to);
    

    Die Datei wird kopiert und bei Dateien kleiner als die Größe von Memory funktioniert das (mit kleinen Anpassungen) auch wunderbar, doch sobald sie größer sind kommt nur noch Mist beim Kopieren raus (.exe Dateien werden nicht mehr als .exe erkannt u.s.w.).

    Was ist falsch?

    Danke

    M.T.



  • Klappt das mit großen dateien nicht oder mit exe dateien?
    Das letzteres nicht klappt wundert mich nicht: Du musst sowohl die Eingabe als auch die ausgabe datei binär öffnen. Das ist beim kopieren sowieso der sinnvollste modus. Das geht indem du bei fopen zusätzlich zu dem r bzw. dem w ein b eingibst:

    file_from = fopen(from, "rb");
    

    btw:
    Das hat gar nichts mit winAPI zu tun. Nimm CreateFile/ReadFile/WriteFile, dann bist du hier richtig. 🙂



  • Nimm CreateFile/ReadFile/WriteFile, dann bist du hier richtig. 🙂

    Da kann ich doch gleich wieder richtig schön klugscheissen: CopyFile() reicht auch. 😃



  • ich auch:
    CopyFileEx ist aus 2 gründen besser als CopyFile:

    The CopyFileEx function provides two additional capabilities. CopyFileEx can call a specified callback function each time a portion of the copy operation is completed, and CopyFileEx can be canceled during the copy operation.

    🙂



  • Ich würde sagen, cd9000 hat die Goldmedaille verdient im Klugscheissen 😉



  • Ich würd mal sagen, das CopyFileEx nicht unter Windows 95 funktioniert und dann sollte man das ganze auch lassen.



  • Hmm, Win95-Fetischist hat sogar recht.



  • Thanks @ all

    🙂

    M.T.



  • Das letzteres nicht klappt wundert mich nicht: Du musst sowohl die Eingabe als auch die ausgabe datei binär öffnen.

    Mhmh... Wie öffnet man denn eine Datei binär, wenn man ReadFile() verwendet?



  • ReadFile liest immer Bytes, unabhängig vom Inhalt der Datei. Daher arbeitet ReadFile immer "binär".

    Warum hast du diesen alten Thread hochgeholt und keinen neuen eröffnet?



  • Ich hab das hier noch drangehängt, weil dieser Thread ziemlich genau meinem Problem entsprach.
    Aber nochmal zu ReadFile(): Wenn ich damit eine exe-Datei auslese, geschieht das nicht in den Packeten, die ich als Parameter angegeben habe. Ich nehme an, das liegt an den vielen Sonderzeichen, oder?



  • Na dann wollen wir doch auch noch mal klugscheißen: SHFileOperation(). :p da ist schon alles dabei, Fortschrittsanzeige, Abbrechen-Schaltfläche, Animation, ...



  • Luckie: Ich hab in der MSDN keine Möglichkeit gefunden, mit dieser Funktion eine Datei auszulesen.

    Copies, moves, renames, or deletes a file system object.



  • Um es jetzt mal auf den Punkt zu bringen: Woran scheitert das auslesen einer Datei mit ReadFile() und womit kann ich sie dann auslesen, wenn nicht mit ReadFile() wenn ich bei den WinApi-Funktionen bleiben will und nicht auf die C-File-Pointer verfallen will 😉



  • Guest2891 schrieb:

    Ich hab das hier noch drangehängt, weil dieser Thread ziemlich genau meinem Problem entsprach.
    Aber nochmal zu ReadFile(): Wenn ich damit eine exe-Datei auslese, geschieht das nicht in den Packeten, die ich als Parameter angegeben habe. Ich nehme an, das liegt an den vielen Sonderzeichen, oder?

    Mit Packeten - meinst Du damit Bytes ?
    Was liefert ReadFile() denn zurück ?
    bzw. was liefert GetLastError() ?

    ReadFile() weiss gar nicht was nen Sonderzeichen ist, es liest einfach nur nNumberOfBytesToRead Bytes ein und fertig...



  • Ok, es liegt daran, dass in Exe-Dateien "\x00"s enthalten, was das heißt, muss ich glaub ich keinem erklären..
    Hab es jetzt so gebaut:
    unsigned long written;

    int inBuffer[1024];
    	ReadFile(hFile,
    		(char*) inBuffer,
    		1024,
    		&written,
    		NULL);
    

    Danke an alle



  • Möchte noch jemand etwas Senf? 😉

    Nenn die Variable read und nicht written, denn es werden keine Bytes auf die Platte geschrieben.



  • Ok, Variable ist umbenannt... 😉 Ich lese die exe-Datei aus, um sie dann zu senden... Doch die Ausleseroutine arbeitet noch nicht immer perfekt, meistens wird zu wenig gesendet

    int inBuffer[LENGTH_FOR_SEND];
    ZeroMemory(inBuffer, LENGTH_FOR_SEND);
    unsigned long nBytesRead = 0;
    HANDLE hFile;
    
    hFile = CreateFile(Pfad.c_str(), 
    	FILE_READ_DATA,
    	FILE_SHARE_READ,
    	NULL,
    	OPEN_EXISTING,
    	FILE_ATTRIBUTE_NORMAL,
    	NULL);
    
    if(hFile == NULL)
    	return false;
    
    while(true)
    {
    	ReadFile(hFile, (char*) &inBuffer, LENGTH_FOR_SEND + strlen(size), &nBytesRead, NULL);
    
    	if(nBytesRead < 1)
    		break;
    
    	MessageBox(NULL, (char*) inBuffer, "Information", MB_ICONINFORMATION);
    
    	if(nBytesRead % LENGTH_FOR_SEND == 0)
    		send(sock, (const char*) inBuffer, LENGTH_FOR_SEND, 0);
    	else
    		send(sock, (const char*) inBuffer, LENGTH_FOR_SEND % nBytesRead, 0);
    
    	ZeroMemory(inBuffer, LENGTH_FOR_SEND);
    }
    
    CloseHandle(hFile);
    

    Sieht jemand einen Fehler?

    Danke

    Remote Viewer



  • Ich verstehe das nich ganz: was ist size?
    Du liest doch LENGTH_FOR_SEND + strlen(size) Bytes aus, sendest aber immer max. LENGTH_FOR_SEND Bytes 😕

    if(nBytesRead % LENGTH_FOR_SEND == 0) 
            send(sock, (const char*) inBuffer, LENGTH_FOR_SEND, 0); 
        else 
            send(sock, (const char*) inBuffer, LENGTH_FOR_SEND % nBytesRead, 0);
    

    Angenommen LENGTH_FOR_SEND ist 1024 und nBytesRead 980, so wurden doch 980 Bytes gelesen, du sendest aber nur 44 (1024%980). Warum dann nicht einfach so:

    send(sock, (const char*) inBuffer, nBytesRead, 0);
    

    Hab schon ewig nicht mehr C/C++ gecodet, also Fehler in keinster Weise ausgeschlossen 🙄


Anmelden zum Antworten