ReadFile Асинхронный - ISO файлы C ++ - PullRequest
1 голос
/ 21 февраля 2012

В моем приложении на c ++ я пытаюсь прочитать iso-файл асинхронно createfile - с наложенным флагом и после него - readfile. Однако, когда я пытаюсь этот код на простой файл (например, TXT-файл), он работает. но когда я запускаю этот код в iso-файле - он не работает. Я видел в MSDN, что сжатый файл может быть прочитан только при синхронизации вызовов readfile. файлы iso находятся в этой категории? если да - есть ли у вас другие предложения, как читать асинхронные файлы ISO?

это мой код:

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

        }

   }

спасибо

Ответы [ 3 ]

2 голосов
/ 21 февраля 2012

Вы не указали, какое значение вы используете для константы BUF_SIZE, но убедитесь, что это целое число, кратное размеру сектора тома.Это распространенная ошибка при использовании небуферизованных файловых потоков.Документация для FILE_FLAG_NO_BUFFERING в документации CreateFile() гласит:

Существуют строгие требования для успешной работы с файлами, открытыми в CreateFile с использованием флага FILE_FLAG_NO_BUFFERING, подробности см. Буферизация файлов .

Страница примечаний по буферизации файлов:

Как обсуждалось ранее, приложение должно соответствовать определенным требованиям при работе с файлами, открытыми с помощью FILE_FLAG_NO_BUFFERING,Применяются следующие особенности:

  • Размеры доступа к файлу, включая необязательное смещение файла в структуре OVERLAPPED, если оно указано, должны соответствовать числу байтов, кратному целому числу сектора томаразмер.Например, если размер сектора составляет 512 байт, приложение может запросить чтение и запись в 512, 1024, 1536 или 2048 байт, но не в 335, 981 или 7 171 байт.

  • Адреса буфера доступа к файлу для операций чтения и записи должны быть выровнены по физическому сектору, что означает выравнивание по адресам в памяти, которые являются целыми числами, кратными размеру физического сектора тома.В зависимости от диска это требование может не выполняться.

Разработчики приложений должны принять к сведению новые типы устройств хранения данных, представленных на рынке, с размером сектора физических носителей, равным4,096 байт.

В моей системе это значение равно 4 КБ, и чтение всего, что меньше 4 КБ, приводит к ошибкам.Во многих примерах кода Microsoft 1K является размером буфера по умолчанию, поэтому адаптация примеров часто приводит к ошибкам с небуферизованным вводом / выводом.

Edit : также убедитесь, что обнулили все членыструктура OVERLAPPED.Вы не устанавливаете элементы Internal и InternalHigh в 0. Всегда очищайте структуру OVERLAPPED следующим образом:

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

Затем вы можете установить смещение файла и дескриптор события.

Редактировать : также учтите следующее примечание о параметре lpNumberOfBytesRead для ReadFile():

Используйте NULL для этого параметраесли это асинхронная операция, чтобы избежать потенциально ошибочных результатов.[...] Подробнее см. В разделе «Примечания».

1 голос
/ 10 октября 2012

Я бы посоветовал обратить особое внимание на перекрывающиеся поля Offset и OffsetHigh, особенно при чтении файла с размером, пересекающим границу 32-разрядного целого числа без знака.Я полагаю, что проблема, с которой вы столкнулись, скрывается там.

0 голосов
/ 21 февраля 2012

Было бы лучше, если бы вы вызывали GetLastError (), как сказал Додо, даже если ошибки нет. То, что возвращает ReadFile, очень помогло бы. Что касается файлов ISO, я думаю, что это сжатые типы файлов. Вы можете посмотреть, чтобы использовать функцию LzRead, хотя. Вот посмотрите на это: "

http://msdn.microsoft.com/en-us/library/windows/desktop/aa365226%28v=vs.85%29.aspx
". Вы также можете открыть файл с помощью LzOpenFile.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365225%28v=vs.85%29.aspx
Надеюсь, это поможет. Не могу найти много на эту тему.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...