C #: использование Directory.GetFiles для получения файлов с фиксированной длиной - PullRequest
0 голосов
/ 08 июня 2009

В каталоге «C: \ temp» есть два файла с именами «GZ96A7005.tif» и «GZ96A7005001.tif». Они имеют разную длину с одинаковым расширением. Теперь я запускаю ниже код:

string[] resultFileNames = Directory.GetFiles(@"C:\temp", "????????????.tif");

'resultFileNames' возвращает два элемента 'c: \ temp \ GZ96A7005.tif' и 'c: \ temp \ GZ96A7005001.tif'. Но окно поиска будет работать нормально. Вот почему и как мне получить, я хочу?

alt text

Ответы [ 4 ]

7 голосов
/ 08 июня 2009

Для Directory.GetFiles ,? означает «ровно ноль или один символ». С другой стороны, вы могли бы использовать DirectoryInfo.GetFiles , для чего? означает «ровно один символ» (очевидно, что вы хотите).

РЕДАКТИРОВАТЬ:

Полный код:

string[] resultFileNames = (from fileInfo in new DirectoryInfo(@"C:\temp").GetFiles("????????????.tif") select fileInfo.Name).ToArray();

Вы, вероятно, можете пропустить ToArray и просто позволить resultFileNames быть IEnumerable<string>.

Люди сообщают, что это не работает для них в MS .NET. Приведенный ниже точный код работает для меня на Mono на Ubuntu Hardy. Я согласен, что на самом деле не имеет смысла иметь два связанных класса, использующих разные соглашения. Тем не менее, это то, что говорится в документации (ссылка выше), и Mono соответствует документам. Если реализация Microsoft не делает, у них есть ошибка:

using System;
using System.IO;
using System.Linq;

public class GetFiles
{
    public static void Main()
    {
        string[] resultFileNames = (from fileInfo in new DirectoryInfo(@".").GetFiles("????????????.tif") select fileInfo.Name).ToArray();
        foreach(string fileName in resultFileNames)
        {
            Console.WriteLine(fileName);
        }
    }
}
5 голосов
/ 08 июня 2009

Я знаю, что читал об этом где-то раньше, но лучшее, что я смог найти сейчас, это ссылка на него в сообщении Рэймонда Чена . Дело в том, что Windows сохраняет короткое (8.3) имя файла для каждого файла с длинным именем для обратной совместимости, а подстановочные знаки сопоставляются как с длинными, так и с короткими именами файлов . Вы можете увидеть эти короткие имена файлов, открыв командную строку и выполнив "dir /x". Обычно получение списка файлов, которые соответствуют ????????.tif (8), возвращает список файлов с 8 или менее символами в имени файла и расширением .tif. Но каждый файл с длинным именем файла также имеет короткое имя файла с 8,3 символами, поэтому все они соответствуют этому фильтру .

В вашем случае GZ96A7005.tif и GZ96A7005001.tif являются длинными именами файлов, поэтому они оба имеют короткое имя 8.3, которое соответствует ????????.tif (что угодно с 8 или более ?).

ОБНОВЛЕНИЕ ... с MSDN :

Потому что этот метод проверяет имена файлов с именем файла 8.3 формат и формат длинного имени файла, шаблон поиска, похожий на "*1*.txt" может вернуть неожиданные имена файлов. За Например, используя шаблон поиска «*1*.txt» возвращает «longfilename.txt» потому что эквивалентное имя файла 8.3 формат "LONGFI~1.TXT".


ОБНОВЛЕНИЕ: в документах MSDN указано другое поведение подстановочного знака "?" в Directory.GetFiles () и DirectoryInfo.GetFiles (). Документация, похоже, неверна. См. Ответ Мэтью Флашена .

1 голос
/ 08 июня 2009

? символ соответствует символу «ноль или один» ... так что из того, что у вас есть, я могу предположить, что ваш шаблон поиска будет соответствовать любому файлу, оканчивающемуся на «.tif» длиной от нуля до двенадцати символов.

Попробуйте добавить другой файл длиной всего три символа с расширением ".tif" и посмотрите, подхватывает ли его и этот код. У меня есть скрытое подозрение, что это будет;)

Что касается поиска Windows, то он определенно не использует тот же алгоритм под капотом. ? символ может иметь совершенно иное значение, чем в спецификации шаблона поиска .Net для метода Directory.GetFiles (string, string).

0 голосов
/ 08 июня 2009
string path = "C:/";
var files = Directory.GetFiles(path)
    .Where(f => f.Replace(path, "").Length == 8);

Немного дорого с заменой строки. Вы можете добавить любое нужное вам расширение.

...