2011-03-10 12 views
6

basitleştirilmiş bir örnek olarak ben hiçbir maçı dosya deseni yapmak birkaç dosya alıyorum set benim sonuçlarında aşağıdakiC# EnumerateFiles joker olmayan eşleşmeleri döndürüyor?

IEnumerable<string> files = Directory.EnumerateFiles(path, @"2010*.xml", 
    SearchOption.TopDirectoryOnly).ToList(); 

yürütme ediyorum. Msdn searchPattern joker karakterine göre "Sıfır veya daha fazla karakter" dir ve bir reg değil. Bir örnek, "2004_someothername.xml" olarak bir dosya adı alıyorum.

Bilgi için klasörde 25.000'den fazla dosya var.

Neler olup bittiği hakkında bir fikri olan var mı?

+1

Eşleşen dosya adlarının bazı örneklerini gönderemez misiniz? – cptScarlet

+0

"Basitleştirilmiş bir örnek olarak" diyorsunuz - gösterdiğiniz kodun iddia ettiğiniz dosyayı gerçekten döndüreceğini test ettiniz mi? Sorunun sadeleştirilmemiş örnekte ortaya çıkması daha olasıdır ...! –

+0

Sağlanan örnek iyi çalışıyor. Sadece test ettim. Bu yüzden düzgün çalışmayan fiili kod gönderebilirseniz lütfen – Stecya

cevap

8

Bu, Windows'un joker karakter eşlemesi nasıl yapıldığından kaynaklanır - , joker aramada kodlanmış 8.3 dosya adlarını içerir, bu da bazı şaşırtıcı eşleşmelere neden olur!

Bu hatanın üstesinden gelmenin bir yolu, işletim sistemi joker eşlemesinde geri gelen tüm dosya sonuçlarını yeniden test etmektir ve joker karakterin her bir (uzun) dosya adına elle karşılaştırılmasıyla sınamaktır. Başka bir yol ise turn off 8.3 filenames altogether via the registry. Komut isteminden joker tabanlı bir del komutu ile önemli (eşleşmeyen) dosyaların silinmesi dahil olmak üzere birçok kez bu konuda yanmış oldum.

sonuçların ikincil bir doğrulama olmadan, herhangi bir kritik üretim kararları veya bir OS dosya/joker maç dayalı herhangi eylemlerde bir dizinde çok sayıda dosya varsa, özellikle eğer çok dikkatli olun Özetlemek gerekirse.

Bu garip davranışın bir explanation İşte.

O'Reilly's site'dan başka bir açıklama.

+2

Hata raporuna bağlantı vermek ister misiniz? –

+3

Bu hata hakkında bir referansınız var mı? System.IO.Directory sınıfını kullanarak, 50.000 dosyayla Powershell'de yeniden oluşturamıyorum. –

+0

@All, bunun nedeni hakkında daha fazla araştırma yaptıktan sonra, cevabımı sorun ve referans açıklamalarıyla güncelledim. –

1

MS hatası için bir çözüm (muhtemelen Windows Dosya Aramasını kullanır, bu da sonuçlarınız için korkunç olur ...), ancak bir çözüm olarak bir çözüm sunar, bu da size bazı ekstra kaldıraç ve sonuçlar üzerinde kontrol sağlar. :

var files = from file in 
     Directory.EnumerateFiles(path, "*", 
     SearchOption.TopDirectoryOnly) 
     where (new FileInfo(file)).Name.StartsWith("2010") && 
      (new FileInfo(file)).Extension == "xml" 
     select dir; 
1

Ben sadece örnek çalıştı ve ben yanlış bir şey yaptığını göremiyorum, bu yüzden ortamınızda ve/veya burada kapsamında değildir "non basitleştirilmiş" kod fazlası var sanırım.

Bu kodu kullandım: my klasör yapısında

Console.WriteLine("Starting..."); 
IEnumerable<string> files = Directory.EnumerateFiles("C:\\temp\\test\\2010", @"2010*.xml", SearchOption.TopDirectoryOnly).ToList(); 

foreach (string file in files) 
{ 
    Console.WriteLine("Found[{0}]", file); 
} 

Console.ReadLine(); 

i ettik aşağıdaki oluşturuldu:

c: \ temp \ testi 2010 \ 2004_something.xml \ c: \ temp \ 2010_abc.xml c \ 2010 \ testi: 2010_def.xml

uygulamanın çıktı \ 2010 \ \ geçici \ test basitçe:

Starting... 
Found[C:\temp\test\2010\2010_abc.xml] 
Found[C:\temp\test\2010\2010_def.xml] 

Gerçek uygulamanızda, senaryonuzda neler olup bittiğine dair biraz daha geribildirim sağlayabilir misiniz? veya sorunu daha küçük bir uygulamada yeniden oluşturabilir misiniz?

2

Sorununuzu aşağıdaki kodla yeniden oluşturabilirim (Üzgünüz, VB). 2010_5000.xml aracılığıyla 2000_0001.xml adında 55.000 sıfır baytlık dosya oluşturur. Sonra 2010 ile başlayan tüm dosyaları arar.Makinemde (Windows 7 SP1 32 bit) sadece 5.000 yerine 5.174 dosya döndürüyor.

Option Explicit On 
Option Strict On 

Imports System.IO 

Public Class Form1 

    Private TempFolder As String = Path.Combine(My.Computer.FileSystem.SpecialDirectories.Desktop, "Temp") 

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 
     CreateFiles() 

     Dim Files = Directory.EnumerateFiles(TempFolder, "2010*.xml", SearchOption.TopDirectoryOnly).ToList() 
     Using FS As New FileStream(Path.Combine(My.Computer.FileSystem.SpecialDirectories.Desktop, "Report.txt"), FileMode.Create, FileAccess.Write, FileShare.Read) 
      Using SW As New StreamWriter(FS, System.Text.Encoding.ASCII) 
       For Each F In Files 
        SW.WriteLine(F) 
       Next 
      End Using 
     End Using 


     DeleteFiles() 
    End Sub 

    Private Sub CreateFiles() 
     If Not Directory.Exists(TempFolder) Then Directory.CreateDirectory(TempFolder) 
     Dim Bytes() As Byte = {} 
     Dim Name As String 
     For Y = 2000 To 2010 
      Trace.WriteLine(Y) 
      For I = 1 To 5000 
       Name = String.Format("{0}_{1}.xml", Y, I.ToString.PadLeft(4, "0"c)) 
       File.WriteAllBytes(Path.Combine(TempFolder, Name), Bytes) 
      Next 
     Next 
    End Sub 
    Private Sub DeleteFiles() 
     Directory.Delete(TempFolder, True) 
    End Sub 
End Class 
+1

VB olmasına rağmen, büyük çaba için +1! :) –

+2

Tüm C# adamlarının C# ile VB sorularına cevap verdiğinden beri anladım. Aslında, şu anda açık olduğum şey bu. –

0

aynı sorunu yaşadı ve benim çözüm sonrası düşündüm bu yazıyı bulmakta olması:

IEnumerable<string> Files = Directory.EnumerateFiles(e.FileName, "*.xml").Where(File => File.EndsWith(".xml", StringComparison.InvariantCultureIgnoreCase)); 

Bu yalnızca ekini test eder ancak ~ .xml sona benim yedek dosyaları eşleşmeleri ortadan kaldırır.

İlgili konular