2016-12-03 2 views
-6

Wie kann ich eine Datei von 100 Byte gelesen, mit ReadFile Funktion und C++Lesen Datei von 100 Byte

habe ich diesen Code, aber es liest die ersten 100 Bytes der Datei

ich das lesen wollen zweiten 100 Bytes

hndl = CreateFileW(L"1.txt", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 
SetFilePointer(hndl, 100, NULL, FILE_BEGIN); 
ReadFile(hndl, pbytReadBuffer, 100, NULL, &ol); 
+0

Warum übergeben Sie eine 'OVERLAPPED' Struktur an' ReadFile'? Ändere '& ol' zu' NULL'. –

+0

Die Logik des Codes, den Sie hier skizziert haben, sieht für mich korrekt aus. Sie haben den korrekten Speicherort gesucht und anschließend einen Lesevorgang von diesem Punkt ausgeführt. Natürlich überprüfen Sie keine Rückgabewerte, daher haben Sie keine Ahnung, ob eine dieser Funktionen fehlschlägt. Es ist auch wichtig, dass Sie eine 'OVERLAPPED'-Struktur an 'ReadFile' übergeben, obwohl Sie die Datei mit der Option' FILE_FLAG_OVERLAPPED' nicht geöffnet haben. –

+1

@CodyGray - 'OVERLAPPED' kann nicht nur mit' FILE_FLAG_OVERLAPPED' verwendet werden, sondern auch mit gesetztem Offset für Lese-/Schreiboperationen - also 'OVERLAPPED' ist absolut korrekt, eine andere Aufgabe - sind sie korrekt initialisiert? – RbMm

Antwort

-1

Sie benötigen Code wie dieser

HANDLE hFile = CreateFile(L"c:\\windows\\notepad.exe", FILE_GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); 
if (hFile != INVALID_HANDLE_VALUE) 
{ 
    OVERLAPPED ov = {}; 
    ov.Offset = 100; 
    UCHAR buf[100]; 
    ULONG cb; 
    if (ReadFile(hFile, buf, sizeof(buf), &cb, &ov)) 
    { 
    } 
    else 
    { 
     GetLastError(); 
    } 
    CloseHandle(hFile); 
} 

Sie nicht SetFilePointer müssen nennen - viel besser Set-Offset direkt in ÜBERLAPPVERBINDUNG Struktur

EDIT

jeder für den Betrieb lesen/schreiben wir den Start Byte-Offset angeben müssen. Dies können wir tun, indem wir Werte in Offset und OffsetHigh von OVERLAPPED setzen.

oder indirekte nur, wenn die Datei geöffnet, wenn synchronen Modus - I/O-Manager die aktuelle Dateiposition in FILE_OBJECT verwenden können - so können wir nicht direkt Satz versetzt - es wird von FILE_OBJECT.CurrentByteOffset bekommen sein. FILE_OBJECT.CurrentByteOffset können wir mit SetFilePointer setzen auch jede Lese-/Schreiboperation diesen Offset aktualisieren - vorwärts zur Zählung der Bytes, die readed/geschrieben. Natürlich ist dies nur richtig, wenn die Datei im synchronen Modus verwendet, wenn alle Operationen mit Datei sequentiell sind

wenn wir direkt in OVERLAPPED Offset verwenden er und verwenden - so FILE_OBJECT.CurrentByteOffset ignoriert wird - dies bedeutet, dass vorherigen Aufruf SetFilePointer - auch alle verloren Wirkung - wird offset von OVERLAPPED und nach Lesevorgang verwendet werden FILE_OBJECT.CurrentByteOffset wird basierend auf Offset + Bytes aktualisiert werden readed

+1

Das könnte funktionieren, aber es erklärt immer noch nicht, warum der Aufruf von 'SetFilePointer' fehlschlagen würde. – Cyclonecode

+0

@Cyclone - für was Sie SetFilePointer verwenden und ich kann nicht wissen, scheitern Sie es in Ihrem Code oder nicht. – RbMm

+0

Ich versuche das, Es ist genau das, was ich will danke – DDD

4

die ReadFile API bietet zwei verschiedene Arten der Ausgangsoffset einzustellen, wenn Synchron tun I/O:

  • Durch Verwendung des implizit gespeicherten Dateizeigers (der über den API-Aufruf SetFilePointer manipuliert werden kann).
  • Oder durch einen expliziten Offset durch die OVERLAPPED Struktur übergeben.

Ihr Code schlägt fehl, da Sie die implizit gespeicherte Dateizeiger setzen, aber dann (vermutlich) passieren eine Null-initialisiert OVERLAPPED Struktur, die den Dateizeiger ignoriert (siehe Synchronization and File Position für weitere Informationen).

Eine der folgenden Lösungen funktioniert. Zunächst mit dem implizit gespeicherten Dateizeiger. Dies ist nützlich, wenn Sie Stücke von einer Datei in aufeinander folgenden Aufrufen lesen möchten:

hndl = CreateFileW(L"1.txt", GENERIC_READ, 0, nullptr, 
        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); 
// Move the file pointer to offset 100 
SetFilePointer(hndl, 100, NULL, FILE_BEGIN); 
// Read contents from the current offset 
DWORD dwBytesRead{0}; 
ReadFile(hndl, pbytReadBuffer, 100, &dwBytesRead, nullptr); 

Alternativ können Sie auch eine OVERLAPPED Struktur passieren den Offset zu übergeben. Dies ignoriert den implizit gespeicherten Dateizeiger. Es ist etwas effizienter, da es nicht zwei Aufrufe der Datei-E/A-API benötigt.

hndl = CreateFileW(L"1.txt", GENERIC_READ, 0, nullptr, 
        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); 
OVERLAPPED ol{}; 
// Set the offset from the start of the file 
ol.Offset = 100; 
ReadFile(hndl, pbytReadBuffer, 100, nullptr, &ol); 

Beachten Sie, dass die Fehlerbehandlung zur Verkürzung in diesen Beispielen aufgeführt ist.In echtem Code müssen Sie immer auf Fehler prüfen.

+0

implizit gespeicherten Dateizeiger kann nur im Fall synchrone I/O verwendet werden - wenn Datei ohne 'FILE_FLAG_OVERLAPPED' erstellt – RbMm

Verwandte Themen