.net - C #: Brug Directory.GetFiles til at hente filer med fast længde

Indlæg af Hanne Mølgaard Plasc

Problem



Katalogen 'C: \ temp' har to filer med navnet 'GZ96A7005.tif' og 'GZ96A7005001.tif'. De har forskellig længde med samme forlængelse. Nu kører jeg under kode:


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


'ResultsFileNames' returnerer to elementer 'c: \ temp \ GZ96A7005.tif' og 'c: \ temp \ GZ96A7005001.tif'.
Men vinduessøgningen fungerer fint. Det er derfor, og hvordan får jeg det jeg vil have?


alt tekst

Bedste reference


Jeg ved, at jeg har læst om dette et eller andet sted før, men det bedste jeg kunne finde lige nu var denne henvisning til det i Raymond Chens blogindlæg. Pointen er, at Windows holder et kort (8.3) filnavn til hver fil med et langt filnavn, for kompatibilitet bagud og filnavn jokertegn matches både lange og korte filnavne . Du kan se disse korte filnavne ved at åbne en kommandoprompt og køre 'dir /x'. Normalt får en liste over filer, der matcher ????????.tif (8), en liste over filer med 8 eller færre tegn i deres filnavn og en .tif-udvidelse. Men hver fil med et langt filnavn har også et kort filnavn med 8,3 tegn, så de alle matcher dette filter . [17]


I dit tilfælde er både GZ96A7005.tif og GZ96A7005001.tif lange filnavne, så de begge har et 8.3 kort filnavn, der matcher ????????.tif (noget med 8 eller flere ? s).


OPDATERING ... fra MSDN: [18]



  Fordi denne metode tjekker imod
  filnavne med både 8.3 filnavn
  format og det lange filnavn format,
  et søgemønster svarende til '*1*.txt'
  kan returnere uventede filnavne. Til
  eksempel ved hjælp af et søgemønster for
  '*1*.txt' returnerer 'longfilename.txt'
  fordi det tilsvarende 8,3 filnavn
  formatet er 'LONGFI~1.TXT'.






UPDATE: MSDN'en beskriver specifikt adfærd for '?' jokertegn i Directory.GetFiles () og DirectoryInfo.GetFiles (). Dokumentationen synes imidlertid at være forkert. Se Matthew Flaschens svar.

Andre referencer 1


For Directory.GetFiles,? betyder 'Nøjagtigt nul eller et tegn.' På den anden side kan du bruge DirectoryInfo.GetFiles, for hvilket? betyder 'Præcis et tegn' (tilsyneladende hvad du vil). [20] [21]


REDIGERE:


Fuld kode:


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


Du kan sandsynligvis springe over ToArray og bare lade resultatFileNames være en IEnumerable<string>.


Mennesker rapporterer, at dette ikke virker for dem på MS .NET. Nedenstående præcise kode virker for mig med på Mono på Ubuntu Hardy. Jeg er enig i, at det ikke er rigtigt fornuftigt at have to relaterede klasser brug forskellige konventioner. Men det er hvad dokumentationen (linket ovenfor) siger, og Mono overholder dokumenterne. Hvis Microsofts implementering ikke har det, har de en fejl:


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);
        }
    }
}

Andre referencer 2


Det ? tegn matcher 'nul eller en' tegn ... så fra hvad du har, kan jeg forestille mig, at dit søge mønster vil matche enhver fil, der slutter i '.tif', der er mellem nul og tolv tegn lang.


Prøv at droppe en anden fil, der kun er tre tegn lang med en '.tif' -udvidelse og se, om koden også henter det. Jeg har en snigende mistanke om, at det vil;)


Hvad angår Windows-søgningen er det mest definitivt ikke at anvende den samme algoritme under emhætten. Det ? tegn kan have en meget anderledes betydning der, end den gør i .Net søgemønster specifikationen for Directory.GetFiles (streng, streng) metode.

Andre referencer 3


string path = "C:/";
var files = Directory.GetFiles(path)
    .Where(f => f.Replace(path, "").Length == 8);


Lidt dyrt med strengen erstatning. Du kan tilføje, hvilken udvidelse du har brug for.