Pregunta

En mi aplicación de C ++, estoy intentando leer el archivo iso asíncrono por createfile, con una bandera superpuesta y después, readfile. sin embargo, cuando pruebo este código en un archivo simple (archivo txt, por ejemplo) funciona.pero cuando ejecuto este código en un archivo iso, falla. Vi en MSDN que el archivo comprimido solo se puede leer mediante llamadas de sincronización de readfile.¿Los archivos iso están en esta categoría? En caso afirmativo, ¿tiene alguna otra sugerencia sobre cómo leer archivos iso asíncronos?

este es mi código:

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

        }

   }

gracias

¿Fue útil?

Solución

No ha publicado qué valor está usando para la constante BUF_SIZE, pero asegúrese de que sea un múltiplo entero del tamaño del sector de volumen. Este es un error común al utilizar secuencias de archivos sin búfer. La documentación de FILE_FLAG_NO_BUFFERING en la documentación de CreateFile() dice:

Existen requisitos estrictos para trabajar con éxito con archivos abiertos con CreateFile usando el indicador FILE_FLAG_NO_BUFFERING. Para obtener más detalles, consulte Almacenamiento en búfer de archivos .

La página sobre notas de almacenamiento en búfer de archivos:

Como se discutió anteriormente, una aplicación debe cumplir con ciertos requisitos al trabajar con archivos abiertos con FILE_FLAG_NO_BUFFERING. Se aplican los siguientes detalles:

  • Tamaños de acceso a archivos, incluido el desplazamiento de archivo opcional en la estructura SUPERPUESTA, si especificado, debe ser para un número de bytes que sea un múltiplo entero del sector de volumen Talla. Por ejemplo, si el tamaño del sector es de 512 bytes, una aplicación puede solicitar lecturas y escrituras de 512, 1.024, 1.536 o 2.048 bytes, pero no de 335, 981 o 7.171 bytes.

  • Las direcciones del búfer de acceso a archivos para operaciones de lectura y escritura deben ser del sector físico alineado, lo que significa alineado en direcciones en la memoria que son múltiplos enteros de la tamaño del sector físico del volumen. Dependiendo del disco, este requisito puede no ser en vigor.

Los desarrolladores de aplicaciones deben tomar nota de los nuevos tipos de dispositivos de almacenamiento introducido en el mercado con un tamaño de sector de medios físicos de 4096 bytes.

En mi sistema, este valor es 4K y leer cualquier cosa menor a 4K a la vez produce errores. En muchas de las muestras de código de Microsoft, 1K es el tamaño de búfer predeterminado, por lo que la adaptación de ejemplos a menudo conduce a errores con E / S sin búfer.

Editar : asegúrese también de poner a cero todos los miembros de la estructura OVERLAPPED. No establece los miembros Internal y InternalHigh en 0. Siempre borre la estructura OVERLAPPED de la siguiente manera:

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

Luego, puede configurar el desplazamiento del archivo y el controlador del evento.

Editar : considere también la siguiente nota sobre el parámetro lpNumberOfBytesRead para ReadFile() :

Utilice NULL para este parámetro si se trata de una operación asincrónica para evitar resultados potencialmente erróneos. [...] Para obtener más información, consulte la sección Comentarios.

Otros consejos

Sugeriría prestar especial atención a los campos Offset y OffsetHigh superpuestos, especialmente al leer un archivo con el tamaño que cruza el límite de un entero sin signo de 32 bits.Creo que el problema al que te enfrentas se esconde allí.

Sería mejor si llama a GetLastError () como dice Dodo incluso si no hay ningún error.Lo que ReadFile está devolviendo sería de gran ayuda.En lo que respecta a los archivos ISO, creo que son tipos de archivos comprimidos.Sin embargo, puede buscar para usar la función LzRead.Aquí tienes un vistazo a esto: "

http://msdn.microsoft.com/en-us/library/windows/desktop/aa365226%28v=vs.85%29.aspx
".También puede abrir el archivo con LzOpenFile.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365225%28v=vs.85%29.aspx
Espero que ayude.No puedo encontrar mucho sobre este tema.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top