filesystem поиск по маске
От: x-code  
Дата: 13.10.18 09:40
Оценка:
В boost::filesystem для итерации по директориям предлагается использовать boost::filesystem::directory_iterator
Все хорошо, но он ищет все подряд, и я не понимаю как в него передать классическую маску поиска (типа "*.ext").
Эту маску должен вводить пользователь, поэтому регулярные выражения не годятся, нужна именно простая привычная всем маска (кстати как она правильно называется?)
Есть ли в бусте подобные решения?
Re: glob patterns
От: Qbit86 Кипр
Дата: 13.10.18 09:50
Оценка:
Здравствуйте, x-code, Вы писали:

XC>простая привычная всем маска (кстати как она правильно называется?)


glob
Глаза у меня добрые, но рубашка — смирительная!
Re: filesystem поиск по маске
От: jazzer Россия Skype: enerjazzer
Дата: 14.10.18 18:44
Оценка:
Здравствуйте, x-code, Вы писали:

XC>В boost::filesystem для итерации по директориям предлагается использовать boost::filesystem::directory_iterator

XC>Все хорошо, но он ищет все подряд, и я не понимаю как в него передать классическую маску поиска (типа "*.ext").
XC>Эту маску должен вводить пользователь, поэтому регулярные выражения не годятся, нужна именно простая привычная всем маска (кстати как она правильно называется?)
XC>Есть ли в бусте подобные решения?


Вообще-то маска элементарно транслируется в regex:
. -> \. (точно так же \^ \[ \$ \\)
? -> .
* -> .*
этого должно быть достаточно, чтоб получить базовый регексп, то есть маска *[1].* превратится в регэксп .*\[1]\.\*
а дальше std::regex("aaa", std::regex::basic) (вместо "ааа" регэксп)
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[2]: filesystem поиск по маске
От: IID Россия  
Дата: 15.10.18 04:35
Оценка: 4 (1)
Здравствуйте, jazzer, Вы писали:

J>Вообще-то маска элементарно транслируется в regex:


Одна беда, простая маска может использоваться в ядре (через Win/Native API), и способна значительно усечь как трафик данных в юзермод, так и количество сисколлов.
kalsarikännit
Re[3]: filesystem поиск по маске
От: jazzer Россия Skype: enerjazzer
Дата: 16.10.18 16:44
Оценка:
Здравствуйте, IID, Вы писали:

IID>Одна беда, простая маска может использоваться в ядре (через Win/Native API), и способна значительно усечь как трафик данных в юзермод, так и количество сисколлов.


С учетом того, что в каждом шелле свои варианты синтаксиса маски, я бы очень удивился, если бы этим занималось ядро.
Но если вдруг это действительно так, то это очень интересно, поделись ссылкой, плиз.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[4]: filesystem поиск по маске
От: IID Россия  
Дата: 16.10.18 17:13
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Здравствуйте, IID, Вы писали:


IID>>Одна беда, простая маска может использоваться в ядре (через Win/Native API), и способна значительно усечь как трафик данных в юзермод, так и количество сисколлов.


J>С учетом того, что в каждом шелле свои варианты синтаксиса маски, я бы очень удивился, если бы этим занималось ядро.


Шеллам никто не мешает приводить свои маски к системным + делать свой постпроцессинг.
Впрочем всё проще. В POSIX никто и не думал об оптимизациях. Поэтому сисколл getdents[64] не предполагает передачу ему маски, и шарашит в ответ всё подряд.

J>Но если вдруг это действительно так, то это очень интересно, поделись ссылкой, плиз.


NtQueryDirectoryFile
(Функции WIN API FindFirstFile/FindNextFile построены на её базе)

Параметр FileName

An optional pointer to a caller-allocated Unicode string containing the name of a file (or multiple files, if wildcards are used) within the directory specified by FileHandle. This parameter is optional and can be NULL.


Более того, т.к. в Win весь IO может работать в асинхронном режиме — то и перечисление каталога тоже можно сделать асинхронным. Правда до уровня WinApi эта фича не доехала, оставшись Native.
kalsarikännit
Re: filesystem поиск по маске
От: c-smile Канада http://terrainformatica.com
Дата: 16.10.18 20:27
Оценка: 8 (1)
Здравствуйте, x-code, Вы писали:

Вот эта функция из Sciter SDK headers делает то что тебе нужно:
template <typename CT >
    inline int match ( slice<CT> cr, const CT *pattern )
    {
      const CT AnySubstring = '*';
      const CT AnyOneChar = '?';
      const CT AnyOneDigit = '#';

      const CT    *str = cr.start;
      const CT    *wildcard = 0;
      const CT    *strpos = 0;
      const CT    *matchpos = 0;

      charset<CT> cset;

      for (;;)
      {
        if ( *pattern == AnySubstring )
        {
          wildcard = ++pattern;
          strpos = str;
          if ( !matchpos ) matchpos = str;
        }
        else if ( *str == '\0' || str >= cr.end() )
        {
          return ( *pattern == '\0' ) ? int( matchpos - cr.start ) : -1;
        }
        else if ( *pattern == '[' )
        {
          pattern++;
          cset.parse ( pattern );
          if ( !cset.valid ( *str ) )
            return -1;
          if ( !matchpos )
            matchpos = str;
          str += 1;
        }
        else if ( *str == *pattern || *pattern == AnyOneChar )
        {
          if ( !matchpos ) matchpos = str;
          str += 1;
          pattern += 1;
        }
        else if (*pattern == AnyOneDigit)
        {
          if (isdigit(*str)) {
            if (!matchpos) matchpos = str;
            str++;
            pattern++;
          }
          else if (wildcard) {
            str = ++strpos;
            pattern = wildcard;
          }
          else
            return -1;
        }
        else if ( wildcard )
        {
          str = ++strpos;
          pattern = wildcard;
        }
        else
          break;
      }
      return -1;
    }

  template <typename T >
    inline bool slice<T>::like ( const T *pattern ) const
    {
      return match<T>(*this,pattern) >= 0;
    }
Re: filesystem поиск по маске
От: PavelCH  
Дата: 18.10.18 07:52
Оценка: 8 (1)
Вот еще одна примитивная реализация:
// text - это исходный текст
// s - это шаблон. Понимает '*' и '?'
static bool match_pattern(const char* text, const char* s) {
    const char* s2 = s + strlen(s);
    const char* d = text;
    while(s < s2) {
        if(*d == 0)
            return false;
        unsigned char c = *s;
        if(c == '?') {
            s++;
            d++;
        } else if(c == '*') {
            s++;
            if(s == s2)
                return true;
            while(*d) {
                if(*d == *s)
                    break;
                d++;
            }
        } else {
            if(*d++ != *s++)
                return false;
        }
    }
    return true;
}
Нехай щастить
Отредактировано 18.10.2018 13:56 PavelCH . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.