Прежде всего, IOCP здесь абсолютно не связаны. Вы пытаетесь проверить, являются ли операции ввода-вывода (читаются в вашем случае) на дескрипторе асинхронного дескриптора файла немедленным или блокированным. как здесь связан iocp ? Привязать iocp к файлу - это единственный способ получить уведомление, когда ввод-вывод завершен. но это абсолютно не влияет на сам блок ввода / вывода или немедленный возврат. мы можем использовать любой способ уведомления здесь. (APC, IOCP или событие). для вашего теста наиболее просто использовать событие.
тогда давайте посмотрим, как - как вы тестируете - читается блок или возвращается в ваш код? Вы не проверяете это вообще. проверьте эту потребность после возврата ReadFile
- операция завершена или нет. операция ввода / вывода (ReadFile) завершается асинхронно - если вызов API уже возвращает вам управление, но OVERLAPPED
(IO_STATUS_BLOCK
) еще не обновлен системой, что означает, что ввод / вывод еще не завершен. OVERLAPPED
обновлены, мы можем проверить прямой (Internal
член структуры OVERLAPPED
является не STATUS_PENDING
) или по вызову GetOverlappedResult
с bWait [ 1127] установлен в FALSE
Если этот параметр равен
blockquote>FALSE
и операция еще не завершена, функция возвращаетFALSE
, а функцияGetLastError
возвращаетERROR_IO_INCOMPLETE
., поэтому мы можем сказать, что
ReadFile
завершено асинхронно, если следующие 4 кодировки верны:
ReadFile
returnFALSE
GetLastError()
returnERROR_IO_PENDING
GetOverlappedResult(.., FALSE)
returnFALSE
GetLastError()
returnERROR_IO_INCOMPLETE
Вы не проверяете это в собственном коде. вместо этого вы ждете, пока операция io полностью не завершится через
GetOverlappedResult(.., true)
, и занимает некоторое время. и какой смысл это делать?реальный код для теста:
void tt(PCWSTR FileName) { HANDLE hFile = CreateFile(FileName, FILE_GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); if (hFile != INVALID_HANDLE_VALUE) { OVERLAPPED ov {}; if (ov.hEvent = CreateEvent(0, 0, 0, 0)) { char buf[1024]; if (ReadFile(hFile, buf, sizeof(buf), 0, &ov)) { DbgPrint("sync(#1)\n"); } else { switch (GetLastError()) { case ERROR_IO_PENDING: ULONG n; if (GetOverlappedResult(hFile, &ov, &n, FALSE)) { DbgPrint("sync(#2)\n"); } else { switch (GetLastError()) { case ERROR_IO_INCOMPLETE: DbgPrint("async\n"); if (!GetOverlappedResult(hFile, &ov, &n, TRUE)) { __debugbreak(); } break; default: __debugbreak(); } } break; default: __debugbreak(); } } CloseHandle(ov.hEvent); } CloseHandle(hFile); } }
обратите внимание, что результат (синхронный или нет) завершенного чтения зависит от того, являются ли данные файла в кеше. если вы вызываете его для файла, который не был прочитан ранее (то есть данные не в кеше), возможно, API выдает «async», но если вы снова вызовете эту функцию для того же файла - вы в следующий раз быстрее всех (почти на 100%) просмотр "sync (# 2)"
Этот сценарий работал на меня для рекурсивного переименования с каталогами/именами файлов, возможно содержащими пробелы:
find . -type f -name "*\;*" | while read fname; do
dirname=`dirname "$fname"`
filename=`basename "$fname"`
newname=`echo "$filename" | sed -e "s/;/ /g"`
mv "${dirname}/$filename" "${dirname}/$newname"
done
Уведомление sed
выражение, которое в этом примере заменяет все случаи ;
с пространством . Это должно, конечно, быть заменено согласно определенным потребностям.
Есть несколько способов, но использование переименовать
, вероятно, будет самым простым.
Использование одной версии переименовать
:
rename 's/^fgh/jkl/' fgh*
Использование другой версия переименуйте
(то же, что и Judy2K, ответ ):
rename fgh jkl fgh*
Вам следует проверить справочную страницу своей платформы, чтобы узнать, что из вышеперечисленного применимо.
Вот как sed
и mv
могут использоваться вместе для переименования:
for f in fgh*; do mv "$f" $(echo "$f" | sed 's/^fgh/jkl/g'); done
Согласно комментарию ниже, если в именах файлов есть пробелы в них могут потребоваться кавычки, чтобы окружить подфункцию, которая возвращает имя для перемещения файлов в:
for f in fgh*; do mv "$f" "$(echo $f | sed 's/^fgh/jkl/g')"; done
переименование может быть не во всех системах. поэтому, если у вас его нет, используйте оболочку этот пример в оболочке bash
for f in fgh*; do mv "$f" "${f/fgh/xxx}";done