Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 29.03.2022, 23:21   #1
apofioz
Форумчанин
 
Регистрация: 22.01.2014
Сообщений: 313
По умолчанию Асинхронный ввод\вывод

Здравствуйте! Прошу помощи в таком вопросу. Есть пример кода
Код:
#include <windows.h>
#include <iostream.h>


int main()
{
  HANDLE  hFile;     // дескриптор файла
  HANDLE  hEndRead;  // дескриптор события
  OVERLAPPED  ovl;   // структура управления асинхронным доступом к файлу

  // создаем события с автоматическим сбросом
  hEndRead = CreateEvent(NULL, FALSE, FALSE, NULL);
  if (hEndRead == NULL)
    return GetLastError();
    
  // инициализируем структуру OVERLAPPED
  ovl.Offset = 0;         // младшая часть смещения равна 0
  ovl.OffsetHigh = 0;      // старшая часть смещения равна 0
  ovl.hEvent = hEndRead;   // событие для оповещения завершения чтения

  // открываем файл для чтения
  hFile = CreateFile(
    "C:\\demo_file.dat",   // имя файла
    GENERIC_READ,          // чтение из файла
    FILE_SHARE_READ,       // совместный доступ к файлу
    NULL,                  // защиты нет
    OPEN_EXISTING,         // открываем существующий файл
    FILE_FLAG_OVERLAPPED,  // асинхронный ввод
    NULL                   // шаблона нет
  );
  // проверяем на успешное открытие
  if (hFile == INVALID_HANDLE_VALUE)
  {
    cerr << "Create file failed." << endl
      << "The last error code: " << GetLastError() << endl;

    CloseHandle(hEndRead);

    cout << "Press any key to finish.";
    cin.get();

    return 0;
  }
  // читаем данные из файла
  for (;;)
  {
    DWORD  dwBytesRead;
    DWORD  dwRet;
    int    n;

    // читаем одну запись
    if (!ReadFile(
        hFile,           // дескриптор файла
        &n,              // адрес буфера, куда читаем данные
        sizeof(n),       // количество читаемых байтов
        &dwBytesRead,    // количество прочитанных байтов
        &ovl             // чтение асинхронное
      ))
    {
      switch(dwRet = GetLastError())
      {
      case ERROR_IO_PENDING:
        cout << "Read file pending." << endl;
        break;
      case ERROR_HANDLE_EOF:
        cout << endl << "End of the file." << endl;
        cout << "The file is read." << endl;

        // закрываем дескрипторы
        CloseHandle(hFile);
        CloseHandle(hEndRead);

        return 1;
      default:
        cout << "Read file failed." << endl
          << "The last error code: " << dwRet << endl;

        // закрываем дескрипторы
        CloseHandle(hFile);
        CloseHandle(hEndRead);

        return 0;
      }
    }
    // ждем, пока завершится асинхронная операция чтения
    WaitForSingleObject(hEndRead, INFINITE);
    // печатаем число
    cout << n << ' ';
    // увеличивает смещение в файле
    ovl.Offset += sizeof(n);
  }
}
Но программа уходит в бесконечный цикл, не попадает в блок ERROR_HANDLE_EOF, собственно вопрос , почему и как исправить?
apofioz вне форума Ответить с цитированием
Старый 30.03.2022, 08:22   #2
Алексей1153
фрилансер
Форумчанин
 
Регистрация: 11.10.2019
Сообщений: 947
По умолчанию

Цитата:
Сообщение от apofioz Посмотреть сообщение
OVERLAPPED ovl; // структура управления асинхронным доступом к файлу
Цитата:
Сообщение от apofioz Посмотреть сообщение
// инициализируем структуру OVERLAPPED
ovl.Offset = 0; // младшая часть смещения равна 0
ovl.OffsetHigh = 0; // старшая часть смещения равна 0
ovl.hEvent = hEndRead; // событие для оповещения завершения чтения
структура осталась неинициализированной. Вот так будет правильнее:
Код:
OVERLAPPED  ovl{};//инициализация
ovl.hEvent = hEndRead;

с самим overlapped чтением я не разбирался, не подскажу. Но вопрос: зачем оно тут? Можно же просто читать из файла, тут не нужна асинхронность
Алексей1153 вне форума Ответить с цитированием
Старый 31.03.2022, 01:54   #3
apofioz
Форумчанин
 
Регистрация: 22.01.2014
Сообщений: 313
По умолчанию

Цитата:
Сообщение от Алексей1153 Посмотреть сообщение
Можно же просто читать из файла, тут не нужна асинхронность
В задании нужно читать асинхронно. Думаешь мне нужны эти заморочки, не могу разобраться с этим ReadFile/(Ex), уходит в бесконечный цикл.
Код:
switch (dwRet = GetLastError())
            {
            case ERROR_HANDLE_EOF:
                cerr << endl << "Error handle eof" << endl;
                return 1;
            case ERROR_IO_PENDING:
            {
                cout << "Error io eof" << endl;
                int dwRet = 0;
                if (!GetOverlappedResult(hFile, &ovl, &dwReadFile, FALSE))
                {
                    switch (dwRet = GetLastError())
                    {
                    case ERROR_HANDLE_EOF:
                    {
                        cout << "Error handle eof from error io pending"
                            << endl;
                        CloseHandle(hFile);
                        return 1;
                    }
                    break;
                    }
                }
                break;
            }
            }
Вот так работает, но как-то не эстетично, да и чёткого понимания, что я делаю и почему так происходит, у меня нет.(

А вот функция ReadFileEx() не работает, даже, со вставкой выше.
Код:
for (;;)
    {
        DWORD  dwRet;
        int    n;

        // читаем одну запись
        if (!ReadFileEx(
            hFile,       // дескриптор файла
            &n,          // адрес буфера, куда читаем данные
            sizeof(n),   // количество читаемых байтов
            &ovl,        // чтение асинхронное
            completion_routine   // процедура завершения чтения
        ))
        {
            switch (dwRet = GetLastError())
            {
            case ERROR_IO_PENDING:
            {
                cout << "Read file pending." << endl;
                if (!GetOverlappedResult(hFile, &ovl, (DWORD*)n, FALSE))
                {
                    dwRet = GetLastError();
                    switch (dwRet)
                    {
                    case ERROR_SUCCESS:
                        cout << "\tError success" << endl;
                        break;
                    case ERROR_IO_PENDING:
                        cout << "\tError io pending" << endl;
                        break;
                    case ERROR_HANDLE_EOF:
                        cout << "\tError HANDLE eof" << endl;
                        CloseHandle(hFile);
                        return 0;
                    default:
                        cout << "Read file failed." << endl
                            << "The last error code: " << dwRet << endl;

                        // закрываем дескриптор файла
                        CloseHandle(hFile);

                        return 0;
                    }
                }
            }
                break;
            case ERROR_HANDLE_EOF:
                cout << endl << "End of the file." << endl;
                cout << "The file is read." << endl;
                // закрываем дескриптор файла
                CloseHandle(hFile);

                return 0;
            default:
                cout << "Read file failed." << endl
                    << "The last error code: " << dwRet << endl;

                // закрываем дескриптор файла
                CloseHandle(hFile);

                return 0;
            }
        }
Не врубаюсь, что делать, как понять!(

Последний раз редактировалось apofioz; 31.03.2022 в 04:15.
apofioz вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Помогите решить задачку C++: бесформатный ввод/вывод, форматный ввод/вывод david1506 Visual C++ 2 21.10.2015 09:03
Ввод-вывод на СИ Korlet Помощь студентам 1 28.09.2015 17:16
Проблема -Асинхронный ввод Кудаив Помощь студентам 5 20.04.2012 07:44
[C++] Ввод - вывод AquaticSoul Помощь студентам 0 18.04.2010 20:02
Асинхронный ввод/вывод Pblog Обсуждение статей 0 27.05.2007 02:13