Pergunta

Em meu aplicativo c ++, estou tentando ler o arquivo iso assíncrono por createfile - com a bandeira sobreposta e depois - readfile. no entanto, quando tento esse código em um arquivo simples (arquivo txt, por exemplo), ele funciona.mas quando eu executo este código em um arquivo iso - ele falha. Eu vi no MSDN que o arquivo compactado só pode ser lido por chamadas de sincronização readfile.os arquivos iso estão nesta categoria? se sim - você tem outra sugestão de como ler arquivos iso assíncronos?

este é o meu 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");
            }

        }

   }

obrigado

Foi útil?

Solução

Você não postou qual valor está usando para a constante BUF_SIZE, mas certifique-se de que é um múltiplo inteiro do tamanho do setor de volume. Esta é uma armadilha comum ao usar fluxos de arquivos sem buffer. A documentação para FILE_FLAG_NO_BUFFERING na documentação CreateFile() diz:

Existem requisitos estritos para trabalhar com sucesso com arquivos abertos com CreateFile usando o sinalizador FILE_FLAG_NO_BUFFERING, para obter detalhes, consulte Armazenamento em buffer de arquivo .

A página nas notas de armazenamento em buffer de arquivo:

Conforme discutido anteriormente, um aplicativo deve atender a certos requisitos ao trabalhar com arquivos abertos com FILE_FLAG_NO_BUFFERING. As seguintes especificações se aplicam:

  • Tamanhos de acesso ao arquivo, incluindo o deslocamento opcional do arquivo na estrutura OVERLAPPED, se especificado, deve ser para um número de bytes que é um múltiplo inteiro do setor de volume Tamanho. Por exemplo, se o tamanho do setor for 512 bytes, um aplicativo pode solicitar leituras e gravações de 512, 1.024, 1.536 ou 2.048 bytes, mas não de 335, 981 ou 7.171 bytes.

  • Os endereços do buffer de acesso ao arquivo para operações de leitura e gravação devem ser de setor físico alinhados, o que significa alinhados em endereços na memória que são múltiplos inteiros do tamanho do setor físico do volume. Dependendo do disco, este requisito pode não ser aplicada.

Os desenvolvedores de aplicativos devem observar os novos tipos de dispositivos de armazenamento sendo introduzido no mercado com um tamanho de setor de mídia física de 4.096 bytes.

Em meu sistema, esse valor é 4K e ler qualquer coisa menor que 4K por vez produz erros. Em muitos dos exemplos de código da Microsoft, 1 K é o tamanho do buffer padrão, portanto, adaptar exemplos geralmente leva a erros com E / S sem buffer.

Editar : certifique-se também de zerar todos os membros da estrutura OVERLAPPED. Você não define os membros Internal e InternalHigh como 0. Sempre limpe a estrutura OVERLAPPED da seguinte maneira:

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

Em seguida, você pode definir o deslocamento do arquivo e o identificador do evento.

Editar : também considere a seguinte observação sobre o parâmetro lpNumberOfBytesRead para ReadFile() :

Use NULL para este parâmetro se esta for uma operação assíncrona para evitar resultados potencialmente errôneos. [...] Para obter mais informações, consulte a seção Comentários.

Outras dicas

Eu sugeriria prestar muita atenção aos campos Offset e OffsetHigh sobrepostos, especialmente ao ler um arquivo com o tamanho ultrapassando o limite de um inteiro não assinado de 32 bits.Acredito que o problema que você está enfrentando se esconde aí.

Seria melhor se você chamar GetLastError () como dito pelo Dodo mesmo se não houver erro.O que ReadFile está retornando seria de grande ajuda.No que diz respeito aos arquivos ISO, acho que são tipos de arquivos compactados.Você pode procurar usar a função LzRead embora.Aqui, dê uma olhada nisso: "

http://msdn.microsoft.com/en-us/library/windows/desktop/aa365226%28v=vs.85%29.aspx
".Você também pode abrir o arquivo com LzOpenFile.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365225%28v=vs.85%29.aspx
Espero que ajude.Não consigo encontrar muito sobre este tópico.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top