Domanda

Nella mia applicazione c ++ sto cercando di leggere il file iso asincrono da createfile - con flag sovrapposto e dopo di esso - readfile. tuttavia quando provo questo codice su un semplice file (file txt per esempio) funziona.ma quando eseguo questo codice su un file ISO, non funziona. Ho visto in MSDN che il file compresso può essere letto solo tramite chiamate di sincronizzazione readfile.fa i file iso è in questa categoria? se sì, hai altri suggerimenti su come leggere i file ISO in modo asincrono?

questo è il mio codice:

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");
            }

        }

   }

grazie

È stato utile?

Soluzione

Non hai pubblicato il valore che stai utilizzando per la costante BUF_SIZE, ma assicurati che sia un multiplo intero della dimensione del settore del volume. Questa è una trappola comune quando si utilizzano flussi di file senza buffer. La documentazione per FILE_FLAG_NO_BUFFERING nella documentazione CreateFile() dice:

Esistono requisiti rigorosi per lavorare con successo con i file aperti con CreateFile utilizzando il flag FILE_FLAG_NO_BUFFERING, per i dettagli vedere Buffering file .

La pagina sulle note del buffering dei file:

Come discusso in precedenza, un'applicazione deve soddisfare determinati requisiti quando funziona con file aperti con FILE_FLAG_NO_BUFFERING. Si applicano le seguenti specifiche:

  • Dimensioni di accesso ai file, incluso l'offset file opzionale nella struttura OVERLAPPED, se specificato, deve essere per un numero di byte che è un multiplo intero del settore del volume taglia. Ad esempio, se la dimensione del settore è 512 byte, un'applicazione può richiedere letture e scrive di 512, 1.024, 1.536 o 2.048 byte, ma non di 335, 981 o 7.171 byte.

  • Gli indirizzi del buffer di accesso ai file per le operazioni di lettura e scrittura dovrebbero essere settore fisico allineato, che significa allineato su indirizzi in memoria che sono multipli interi di dimensione del settore fisico del volume. A seconda del disco, questo requisito potrebbe non esserlo applicato.

Gli sviluppatori di applicazioni dovrebbero prendere nota dei nuovi tipi di dispositivi di archiviazione introdotto nel mercato con una dimensione del settore multimediale fisico di 4.096 byte.

Sul mio sistema, questo valore è 4K e la lettura di qualsiasi cosa inferiore a 4K alla volta produce errori. In molti esempi di codice di Microsoft, 1K è la dimensione del buffer predefinita, quindi l'adattamento degli esempi spesso porta a errori con I / O senza buffer.

Modifica : assicurati inoltre di azzerare tutti i membri della struttura OVERLAPPED. Non imposti i membri Internal e InternalHigh su 0. Cancella sempre la struttura OVERLAPPED nel modo seguente:

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

Quindi, puoi impostare l'offset del file e l'handle dell'evento.

Modifica : considera anche la seguente nota sul parametro lpNumberOfBytesRead in ReadFile() :

Usa NULL per questo parametro se si tratta di un'operazione asincrona per evitare risultati potenzialmente errati. [...] Per ulteriori informazioni, vedere la sezione Osservazioni.

Altri suggerimenti

Suggerirei di prestare particolare attenzione ai campi Offset e OffsetHigh sovrapposti, specialmente quando si legge un file con la dimensione che supera il limite dell'intero senza segno a 32 bit.Credo che il problema che stai affrontando sia in agguato.

Sarebbe meglio se chiamassi GetLastError () come detto da Dodo anche se non ci sono errori.Ciò che ReadFile restituisce sarebbe di grande aiuto.Per quanto riguarda i file ISO, penso che siano tipi di file compressi.Puoi cercare per usare la funzione LzRead però.Dai un'occhiata a questo: "

http://msdn.microsoft.com/en-us/library/windows/desktop/aa365226%28v=vs.85%29.aspx
".Puoi anche aprire il file con LzOpenFile.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365225%28v=vs.85%29.aspx
Spero che possa aiutare.Non riesco a trovare molto su questo argomento.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top