Странная функциональность в .NET Directory.GetFiles (), когда шаблон поиска содержит 3 символа для расширения - PullRequest
6 голосов
/ 10 января 2012

Я недавно натолкнулся на странную функциональность от Microsoft:

Предположим, что наша папка c:\tmp123 содержит 3 файла -
1.txt
2.txtx
3.txtxt

a) Вызов Directory.GetFiles(@"C:\tmp123", "*.txt") выходов в 3 возвращенных предметах.
б) Вызов Directory.GetFiles(@"C:\tmp123", "*.txtx") выходов в 1 возвращенных элементах.

Согласно Microsoft это ожидаемое поведение (см. Примечание в MSDN ).

Мои вопросы:

  1. Почему Microsoft решила использовать такую ​​странную функциональность?

  2. Как мне преодолеть эту проблему?
    то есть, как у меня есть шаблон поиска, который будет возвращать только расширение *.txt и не будет возвращать *.txtx, *.txtstarngefunctionality и т. д .?

Ответы [ 4 ]

2 голосов
/ 10 января 2012

Причиной этого является обратная совместимость.

Windows изначально создавалась как графический интерфейс поверх MSDOS, в котором были только файлы с 8 символами для имени и максимум 3 для расширения.Расширения файловых систем MSDOS позволили Windows иметь более длинные имена и расширения файлов, но они по-прежнему отображались бы как имена файлов 8.3 в MSDOS.

Поскольку командная строка в Windows является развитием старого интерпретатора команд в MSDOSэто означает, что некоторые «анахроничные» поведения (например, шаблон поиска из 3 букв) были сохранены, чтобы приложения и сценарии, созданные в «старые времена» или «старыми таймерами», не ломались.

(другой пример -Дело в том, что большинство файловых систем Windows нечувствительны к регистру, да, как вы уже догадались, потому что в MSDOS не было кожуха)

1 голос
/ 10 января 2012

Если вы хотите обойти это, вы можете просто получить все пути к файлам

var files = Directory.GetFiles(@"C:\tmp123");

, а затем отфильтруйте их по расширению при необходимости

var txtFiles = files.Where(f => f.EndsWith(".txt"));
var txtxFiles = files.Where(f => f.EndsWith(".txtx"));
0 голосов
/ 25 сентября 2014

Вот еще один обходной путь, который поможет отфильтровать файлы с такими расширениями, как ".txtxt":

var Files = System.IO.Directory.GetFiles("*.txt").Where(item => item.Extension.ToString().ToLower() == ".txt");
0 голосов
/ 10 января 2012

Готов поспорить, что это связано с обратной совместимостью.Я не вижу упомянутой точной проблемы, но в этом посте Раймонда Чена упоминается ряд странностей в этой области:

[...] некоторые причуды соответствия FCBалгоритм сохраняется в Win32, потому что он стал идиомой.

Например, если ваш шаблон заканчивается на .*, .* игнорируется.Без этого правила шаблон *.* соответствовал бы только файлам, которые содержали точку, которая сломала бы, вероятно, 90% всех пакетных файлов на планете, а также мышечную память каждого, поскольку все, кто работал под управлением Windows NT 3.1, рослимир, где *.* означает все файлы.

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

...