#winapi
#winapi
Вопрос:
Я хотел бы узнать о FindFirstFile и следующем первом FindNextFile. Правда ли, что FindFirstFile ВСЕГДА находит ‘.’ (текущую папку), а следующий FindNextFile ВСЕГДА находит ‘..’ (родительскую папку)? Маска, конечно, ‘*’. Я хочу немного ускорить список файлов, могу ли я написать что-нибудь вроде:
h := FindFirstFile('path*' ...) // it finds '.', not process
if h = INVALID_HANDLE_VALUE then ... // some error handling, of course
FindNextFile(...) // skipping '..', I suppose, if '.' has found,
// '..' will be too, no handle validity check
while FindNextFile(...) do
// file/folder processing begins here
Поэтому мне не нужно проверять имена файлов ‘.’ и ‘..’ в каждом цикле. Извините за синтаксис, я думаю, я был понятен, и за мой английский, если я допустил ошибки.
Комментарии:
1. Это бессмысленно и не ускорит его каким-либо измеримым образом, а просто запутывает. Я также не могу найти ничего, что могло бы гарантировать такой порядок. Короче говоря, вообще ничего нельзя сказать в пользу этого.
2. @DavidHeffernan И если «путь» равен «C:», вы просто выбросили две совершенно правильные записи каталога.
3. Единственный реальный способ ускорить перечисление файлов в каталоге — это прямой доступ к MFT . Однако там все усложняется, я бы не стал беспокоиться.
4.
FindFirstFileEx
может быть быстрее, чемFindFirstFile
в некоторых случаях.5. Это также может привести к сбою для файлов в сети, в зависимости от программного обеспечения, запущенного на сервере.
Ответ №1:
Нет никакой гарантии, что первые две записи будут '. '
и '..'
. Таким образом, предлагаемый вами код не может быть использован.
Я полагаю, вы могли бы отслеживать в логическом значении, видели ли вы эти две записи или нет, и если да, пропустить проверки.
Однако проверка этих значений не является вашим узким местом. Перечисление каталогов включает в себя обращения к диску и системные вызовы. Это узкое место. Любая попытка оптимизировать проверку этих элементов запутает ваш код и не даст заметного преимущества в производительности.
Ответ №2:
Спасибо за ответы. Одно из моих увлечений — находить лучшие решения, алгоритмы в коротких основных кодах (при необходимости, вплоть до уровня сборки). В моей практике это казалось правдой, я испытал это. Но я не нашел никакой документации по этому поводу, подумал я, это зависит от внутреннего поведения Find * File и структуры данных жесткого диска. Вот почему я спросил. Еще раз спасибо.
Джонатан: Я действительно использовал FindFirstFileEx с FIND_FIRST_EX_LARGE_FETCH, а не как в примере кода 🙂 Я думал, что использование Ex или not не имеет значения в вопросе.
IInspectable: Вы правы, я не хочу погружаться в MFT 🙂
Я не буду использовать эту форму кода. Я буду использовать — как предлагает Дэвид — переменную, но целочисленный тип для подсчета вхождений с 2, и если счетчик достигает 0, проверки имен больше не нужны.
Комментарии:
1. Это не будет быстрее, и ваш код будет запутан
2. Я понял вас, узкое место, я не могу ускорить вызовы API и доступ к диску, но я следил в disasembler, что делает простое сравнение строк. Это беспокоит (запутывает 🙂 меня. Пожалуйста, не смейтесь и не принимайте меня всерьез, это хобби. Я напишу специализированный ассемблерный код для сравнения unicode ‘.’ и ‘..’. Возможно, я слишком максималист 🙂
3. Делайте это ради удовольствия, но не обманывайте себя, что ваша программа будет работать быстрее.