kostenloser Webspace werbefrei: lima-city


ReadFile und WriteFile - noch zu langsam

lima-cityForumProgrammiersprachenC/C++ und D

  1. Autor dieses Themas

    toolz

    Kostenloser Webspace von toolz

    toolz hat kostenlosen Webspace.

    Hallo! Ich beschäftige mich momentan mit C++ mit ReadFile und WriteFile. Zum Eingewöhnen habe ich mir ein kleines Programm geschrieben, das Dateien kopiert. Dabei will ich gar nicht wissen, wieviele potentielle Fehler ich unbehandelt lasse, sondern freue mich einfach darüber, dass es im Normalfall klappt. Allerdings habe ich anscheinend etwas falsch gemacht, da es viel zu langsam kopiert. Eine 2 MB große Datei z.B. würde mit geschätzten 1 KB/s schon zu lange dauern. Wo liegt das Geschwindigkeitsproblem ist also die Frage:
    #include <windows.h>
    #include <iostream>
    
    using namespace std;
    
    int main () {
    	char pfad[255];
    	cout << "Die zu kopierende Datei angeben: ";
    	cin >> pfad;
    	HANDLE quelle = CreateFile(pfad, GENERIC_READ, FILE_SHARE_READ, null, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, null);
    
    	if (quelle == null) {
    		cout << "Der angegebene Pfad scheint zu keiner Datei zu führen.";
    		cin >> pfad;
    		return 0;
    	}
    
    	cout << "Den Pfad der Zieldatei angeben: ";
    	cin >> pfad;
    
    	HANDLE ziel = CreateFile(pfad, GENERIC_WRITE, 0, null, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, null);
    
    	if (ziel == null) {
    		cout << "Die Datei konnte nicht angelegt werden.";
    		cin >> pfad;
    		return 0;
    	}
    
    	char byte = 0;
    	DWORD gelesen = 0;
    	DWORD geschrieben = 0;
    	while (gelesen == geschrieben) {
    		if (!ReadFile(quelle, &byte, 1, &gelesen, null)) {
    			LPVOID fehler;
    			FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, null, GetLastError(),
    				MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &fehler, 0, null);
    			cout << endl << "Die Quelldatei konnte nicht gelesen werden:" << kEnde << (LPCTSTR) fehler;
    			cin >> pfad;
    			return 0;
    		}
    		if (!WriteFile(ziel, &byte, 1, &geschrieben, null)) {
    			LPVOID fehler;
    			FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, null, GetLastError(),
    				MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &fehler, 0, null);
    			cout << endl<< "Die Zieldatei konnte nicht beschrieben werden:" << kEnde << (LPCTSTR) fehler;
    			cin >> pfad;
    			return 0;
    		}
    	}
    
    	cout << "Die Duplizierung ist abgeschlossen.";
    	cin >> pfad;
    	return 1;
    }
    Würde es evtl. schneller gehen, wenn ich die Größe des Puffers (byte) erhöhe? Allerdings habe ich dann Angst, dass ein Überlauf am Ende der Datei stattfindet...

    Beitrag zuletzt geändert: 30.6.2011 18:18:02 von toolz
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

  3. Hallo toolz,

    eine Datei byte-weise zu kopieren ist natürlich sehr langsam. Um einen Überlauf musst Du Dir keine sorgen machen, da ReadFile() ja ausgibt wieviele Bytes es gelesen hat (4. Argument) und genau diese Anzahl übergibst Du wieder bei WriteFile() (3. Argument).
    #include <windows.h>
    #include <iostream>
    
    using namespace std;
    
    int main () {
        char pfad[MAX_PATH];
        cout << "Die zu kopierende Datei angeben: ";
        cin >> pfad;
        HANDLE quelle = CreateFile(pfad, GENERIC_READ, FILE_SHARE_READ, null, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, null);
    
        if (quelle == null) {
            cout << "Der angegebene Pfad scheint zu keiner Datei zu führen.";
            cin >> pfad;
            return 1;
        }
    
        cout << "Den Pfad der Zieldatei angeben: ";
        cin >> pfad;
    
        HANDLE ziel = CreateFile(pfad, GENERIC_WRITE, 0, null, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, null);
    
        if (ziel == null) {
            cout << "Die Datei konnte nicht angelegt werden.";
            cin >> pfad;
            CloseHandle(quelle);
            return 1;
        }
    
        char byte[4096];
        DWORD count;
    
        while (true) {
            if (!ReadFile(quelle, &byte, sizeof(byte), &count, null)) {
                LPVOID fehler;
                FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, null, GetLastError(),
                    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &fehler, 0, null);
                cout << endl << "Die Quelldatei konnte nicht gelesen werden:" << kEnde << (LPCTSTR) fehler;
                cin >> pfad;
                CloseHandle(quelle);
                CloseHandle(ziel);
                return 1;
            }
    
            if(!count) break;
    
            if (!WriteFile(ziel, &byte, count, null , null)) {
                LPVOID fehler;
                FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, null, GetLastError(),
                    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &fehler, 0, null);
                cout << endl<< "Die Zieldatei konnte nicht beschrieben werden:" << kEnde << (LPCTSTR) fehler;
                cin >> pfad;
                CloseHandle(quelle);
                CloseHandle(ziel);
                return 1;
            }
        }
    
        cout << "Die Duplizierung ist abgeschlossen.";
        cin >> pfad;
        CloseHandle(quelle);
        CloseHandle(ziel);
        return 0;
    }
    Allerdings hättest Du es mit CopyFile() wesentlich einfacher. Im übrigen bedeutet bei Programmen ein Rückgabewert ungleich 0, dass ein Fehler passiert ist und 0, dass alles in Ordnung ist;-)
  4. Noch eine zusätzliche kleine Anmerkung: Durch kompilieren im Releas-Modus, anstatt des Debug-Modus lässt sich die Geschwindigkeit von Programmen bis zu vervierfachen :thumb:.
  5. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

Dir gefällt dieses Thema?

Über lima-city

Login zum Webhosting ohne Werbung!