Frage

In meiner C ++ - Anwendung versuche ich, die ISO-Datei asynchron nach createfile zu lesen - mit überlappendem Flag und danach - readfile. Wenn ich diesen Code jedoch in einer einfachen Datei (z. B. txt-Datei) versuche, funktioniert er.Aber wenn ich diesen Code in einer ISO-Datei ausführe, schlägt er fehl. Ich habe in MSDN gesehen, dass komprimierte Dateien nur durch Synchronisierungsaufrufe für Lesedateien gelesen werden können.Gehört ISO-Dateien zu dieser Kategorie? Wenn ja - haben Sie einen anderen Vorschlag zum asynchronen Lesen von ISO-Dateien?

das ist mein Code:

int _tmain(int argc, _TCHAR* argv[])
{


HANDLE hFile;
    DWORD NumberOfBytesRead = 0, dw;
    BYTE *buf = (BYTE*)malloc(BUF_SIZE*sizeof(BYTE));
    OVERLAPPED overlapped;
    overlapped.Offset = overlapped.OffsetHigh = 0;  
    memset(buf, 0, 1024);

overlapped.hEvent = CreateEvent(NULL, true, false, NULL); 
if(NULL == overlapped.hEvent)
    printf("error");

hFile = CreateFile("xxx.iso",
                  GENERIC_READ,
                  FILE_SHARE_READ,
                  NULL,
                  OPEN_EXISTING,
    FILE_FLAG_OVERLAPPED | FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING , 
                  NULL);



if (hFile == INVALID_HANDLE_VALUE)
        printf("invalid hfile\n");

   int i;   
   i= ReadFile(hFile,
                 buf,
                 BUF_SIZE,
                 &NumberOfBytesRead,
        &overlapped);
   if( GetLastError() == ERROR_IO_PENDING)
   {


       dw = WaitForSingleObject(overlapped.hEvent, INFINITE);
    if(dw ==  WAIT_OBJECT_0)
        if (GetOverlappedResult(hFile,&overlapped,&NumberOfBytesRead, TRUE) != 0)   
        {
            if (NumberOfBytesRead != 0) 
            {
                printf("!!!\n");
            }

        }

   }

danke

War es hilfreich?

Lösung

Sie haben nicht angegeben, welchen Wert Sie für die BUF_SIZE-Konstante verwenden, stellen jedoch sicher, dass es sich um ein ganzzahliges Vielfaches der Größe des Volume-Sektors handelt. Dies ist eine häufige Gefahr, wenn ungepufferte Dateistreams verwendet werden. Die Dokumentation für FILE_FLAG_NO_BUFFERING in der CreateFile()-Dokumentation lautet:

Es gibt strenge Anforderungen für die erfolgreiche Arbeit mit Dateien, die mit CreateFile mit dem Flag FILE_FLAG_NO_BUFFERING geöffnet wurden. Weitere Informationen finden Sie unter Dateipufferung .

Die Seite mit den Anmerkungen zur Dateipufferung:

Wie bereits erwähnt, muss eine Anwendung beim Arbeiten bestimmte Anforderungen erfüllen mit Dateien, die mit FILE_FLAG_NO_BUFFERING geöffnet wurden. Es gelten folgende Besonderheiten:

  • Dateizugriffsgrößen, einschließlich des optionalen Dateiversatzes in der OVERLAPPED-Struktur, falls angegeben, muss für eine Anzahl von Bytes sein, die ein ganzzahliges Vielfaches des Volume-Sektors ist Größe. Wenn die Sektorgröße beispielsweise 512 Byte beträgt, kann eine Anwendung Lesevorgänge und anfordern schreibt von 512, 1.024, 1.536 oder 2.048 Bytes, aber nicht von 335, 981 oder 7.171 Bytes.

  • Dateizugriffspufferadressen für Lese- und Schreibvorgänge sollten ein physischer Sektor sein ausgerichtet, dh auf Adressen im Speicher ausgerichtet, die ganzzahlige Vielfache der sind Größe des physischen Sektors des Volumens. Abhängig von der Festplatte ist diese Anforderung möglicherweise nicht erfüllt erzwungen.

    Anwendungsentwickler sollten neue Arten von Speichergeräten beachten mit einer Größe des physischen Mediensektors von 4.096 Bytes auf den Markt gebracht.

    Auf meinem System beträgt dieser Wert 4 KB, und das gleichzeitige Lesen von weniger als 4 KB führt zu Fehlern. In vielen Codebeispielen von Microsoft ist 1 KB die Standardpuffergröße. Daher führt das Anpassen von Beispielen häufig zu Fehlern mit ungepufferten E / A.

    Bearbeiten : Stellen Sie außerdem sicher, dass alle Mitglieder der OVERLAPPED-Struktur auf Null gesetzt sind. Sie setzen die Mitglieder Internal und InternalHigh nicht auf 0. Löschen Sie die OVERLAPPED-Struktur immer wie folgt:

    OVERLAPPED overlapped;
    ZeroMemory(&overlapped, sizeof(OVERLAPPED));
    

    Anschließend können Sie den Datei-Offset und das Ereignis-Handle festlegen.

    Bearbeiten : Beachten Sie auch den folgenden Hinweis zum Parameter lpNumberOfBytesRead für ReadFile() :

    Verwenden Sie NULL für diesen Parameter, wenn dies eine asynchrone Operation ist, um möglicherweise fehlerhafte Ergebnisse zu vermeiden. [...] Weitere Informationen finden Sie im Abschnitt Bemerkungen.

Andere Tipps

Ich würde empfehlen, die Felder Offset und OffsetHigh der Überlappung genau zu beachten, insbesondere beim Lesen einer Datei mit einer Größe, die die Grenze einer 32-Bit-Ganzzahl ohne Vorzeichen überschreitet.Ich glaube, das Problem, mit dem Sie konfrontiert sind, lauert dort.

Es ist besser, wenn Sie GetLastError () wie von Dodo angegeben aufrufen, auch wenn kein Fehler vorliegt.Was ReadFile zurückgibt, wäre eine sehr große Hilfe.Was ISO-Dateien betrifft, denke ich, dass es sich um komprimierte Dateitypen handelt.Sie können jedoch nachschlagen, um die LzRead-Funktion zu verwenden.Schauen Sie sich das hier an: "

http://msdn.microsoft.com/en-us/library/windows/desktop/aa365226%28v=vs.85%29.aspx
".Sie können die Datei auch mit LzOpenFile öffnen.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365225%28v=vs.85%29.aspx
Hoffe es würde helfen.Ich kann nicht viel zu diesem Thema finden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top