Переименуйте несколько файлов на основе шаблона в Unix

Прежде всего, IOCP здесь абсолютно не связаны. Вы пытаетесь проверить, являются ли операции ввода-вывода (читаются в вашем случае) на дескрипторе асинхронного дескриптора файла немедленным или блокированным. как здесь связан iocp ? Привязать iocp к файлу - это единственный способ получить уведомление, когда ввод-вывод завершен. но это абсолютно не влияет на сам блок ввода / вывода или немедленный возврат. мы можем использовать любой способ уведомления здесь. (APC, IOCP или событие). для вашего теста наиболее просто использовать событие.

тогда давайте посмотрим, как - как вы тестируете - читается блок или возвращается в ваш код? Вы не проверяете это вообще. проверьте эту потребность после возврата ReadFile - операция завершена или нет. операция ввода / вывода (ReadFile) завершается асинхронно - если вызов API уже возвращает вам управление, но OVERLAPPED (IO_STATUS_BLOCK) еще не обновлен системой, что означает, что ввод / вывод еще не завершен. OVERLAPPED обновлены, мы можем проверить прямой (Internal член структуры OVERLAPPED является не STATUS_PENDING) или по вызову GetOverlappedResult с bWait [ 1127] установлен в FALSE

Если этот параметр равен FALSE и операция еще не завершена, функция возвращает FALSE, а функция GetLastError возвращает ERROR_IO_INCOMPLETE .

blockquote>

, поэтому мы можем сказать, что ReadFile завершено асинхронно, если следующие 4 кодировки верны:

  1. ReadFile return FALSE
  2. GetLastError() return ERROR_IO_PENDING
  3. GetOverlappedResult(.., FALSE) return FALSE
  4. GetLastError() return ERROR_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)"

227
задан jww 20 March 2019 в 02:31
поделиться

5 ответов

Этот сценарий работал на меня для рекурсивного переименования с каталогами/именами файлов, возможно содержащими пробелы:

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 выражение, которое в этом примере заменяет все случаи ; с пространством . Это должно, конечно, быть заменено согласно определенным потребностям.

1
ответ дан 23 November 2019 в 03:48
поделиться

Есть несколько способов, но использование переименовать , вероятно, будет самым простым.

Использование одной версии переименовать :

rename 's/^fgh/jkl/' fgh*

Использование другой версия переименуйте (то же, что и Judy2K, ответ ):

rename fgh jkl fgh*

Вам следует проверить справочную страницу своей платформы, чтобы узнать, что из вышеперечисленного применимо.

271
ответ дан 23 November 2019 в 03:48
поделиться
rename fgh jkl fgh*
13
ответ дан 23 November 2019 в 03:48
поделиться

Вот как 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
107
ответ дан 23 November 2019 в 03:48
поделиться

переименование может быть не во всех системах. поэтому, если у вас его нет, используйте оболочку этот пример в оболочке bash

for f in fgh*; do mv "$f" "${f/fgh/xxx}";done
73
ответ дан 23 November 2019 в 03:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: