C#, поиск файла по маске.

Или небольшая заметка про странный глюк (на самом деле фичу) MS и кривофикс к ней.

Словил странный баг при поиске файлов по маске, функцией Directory.GetFiles();

Оказалось, что при задании маски вида *.htm, в выборке окажутся все файлы с расширением, длина которого больше трех совпадающих символов, т.е. и *.htm и *.html и *.htmепрст, и т.д. Срабатывает это для файлов с расширениями размером три символа и больше.

Т.е. на *.ph оно найдет только файлы с расширением ph, а на *.a — только файлы с расширением a

Этот баг распространяется только на последнее расширение. Если в имени файла есть конструкция типа *.tmp.php, например admin.tmp.php, то при задании маски *.php расширение tmp будет, слава Ктулху, проигнорировано.

Оказалось, что это не баг, а фича, и об этом прямо написано в MSDN:

Если указанное расширение имеет длину ровно три символа, метод возвращает файлы с расширениями, которые начинаются с указанного расширения. Например, «*. xls» возвращает оба значения: «Book.xls» и «Book.xlsx».

Не знаю, как создатели DOS смогли заговнять и испортить самую простую операцию, которая работала у них, как минимум, с 1989 года, но факт. Заговняли.

В общем, я теряюсь в догадках.

Кривофикс

Это, конечно же, довольно коряво. Наверное, можно было бы решить с помощью регулярных выражений, но я поступил следующим образом:

1. Создал функцию, которая будет вытаскивать однозначное расширение и из заданной маски, и из поданного на вход файла:

private string GetExtension(string FileName)
{
    FileName = FileName.Replace('*', '_');
    FileName = FileName.Replace('?', '-');
    FileInfo fi = new FileInfo(FileName);
    return fi.Extension;
}

Замены Replace(...) тут для того, чтобы класс FileInfo не выпал в Exeption, если ему подать что-то вида *.html, т.к. FileInfo не принимает имен с недопустимыми символами, к которым относятся и маски подстановки. В определении расширений класс FileInfo такого глюка не имеет, и отличает file.html от file.htm. И тоже не признает двойные расширения, учитывая только последнее.

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

string[] files = Directory.GetFiles(Path, Mask, SearchOptions);

3. Получаем расширение маски:

string MaskExt = GetExtension(Mask);

4. Далее обрабатываем выходной массив. Например, тут я добавлял его в List<string> с именем FoundFiles. Мне надо было искать файлы по маскам, и нужно было, чтоб *.htm и, например, *.html различались.

Например, я просто сравнивал расширение от маски файла с расширением от имени файла, и если оно совпадало — добавлял в результирующий список FoundFiles:

string FileExt = GetExtension(filename);
if (FileExt == MaskExt)
{
    FoundFiles.Add(filename);
}

Или относительно полностью:

string MaskExt = GetExtension(Mask);
//[...]
string[] files = Directory.GetFiles(Path, Mask, SearchOptions);
foreach (string filename in files)
{
    string FileExt = GetExtension(filename);
    if (FileExt == MaskExt)
    {
        FoundCtr++;
        FoundFiles.Add(filename);
    }
}

Пакетный конвертер (перекодировщик) текстовых файлов v 0.0.2b

Изначально писалось для товарищей в 2016 г., поскольку почему-то все пакетные конвертеры/перекодировщики текстовых файлов были исключительно платными, во всяком случае на тот момент и под Windows.

Основные возможности

— Пакетная перекодировка текстовых файлов
— Создание полного дерева каталогов для перекодированных файлов
— Доступен расширенный список кодировок (все кодировки, поддерживаемые .NET Framework)

Изменения в версии v 0.0.2b

— Добавлена возможность сохранять изменения в целевой каталог (перезаписывать файлы)
— Программа по умолчанию работает в портативном режиме, настройки хранятся в каталоге с программой.
— Изменен формат файла настроек на XML

Системные требования

Windows XP/7/8/10
.NET Framework 2.0.
256 Мб ОП

Ключи командной строки

/help — эта помощь
/np — отключение портативного режима
(настройки программы хранятся в C:\Users\<пользователь>\AppData\Local\BatchTextConverter\)

Разработчики

D. Larin
Chang Min Ho
PunkArr[]

Скриншоты


Главный экран

Остальные скриншоты

Исходники

Репозиторий на GitHub

Скачать

Портативная версия

Начали блокировать доступ к VPN-провайдерам.

С удивлением узнал, что vpnbook.com заблокирован.

А перед этим Firefox еще и заругался на подмененный сертификат. Так что и сертификаты подменить пытаются. Самое прикольное, что соединение с vpnbook не блокируется. Только без доступа к сайту пароль не обновить. Придется потом думать, как это сделать через Tor.

Dialog — псевдографический оконный интерфейс в bash-скриптах

Оказывается, в bash-скриптах можно организовать псевдографический оконный интерфейс с помощью команды dialog. Не буду тут подробно про нее расписывать, потом покажу ее использование на реальном проекте, а пока заметка от склероза.

Краткий мануал на английском

Копия в PDF

Примеры скриптов на GitHub

Скачать в архиве