2012-01-18 26 views
6

text file'dan daha hızlı ve daha akıllı bir şekilde okunmanın mümkün olup olmadığını bilmek istiyorum.Bir Metin Dosyasından Nasıl Daha Hızlı/Daha Akıllı Okunur?

Çağrı bu "parçası":

ID:1; 
FIELD1 :someText; 
FIELD2 :someText; 
FIELD3 :someText; 
FIELD4 :someText; 
FIELD5 :someText; 
FIELD6 :someText; 
FIELD7 :someText; 
FIELD8 :someText; 
END_ID : 
01: someData; 
02: someData; 
... 
... 
48: someData; 
ENDCARD: 

Bir metin dosyasına onlardan binlerce var

Bu text file bir benim verilerin tipik biçimidir.

LINQ "part" tarafından "part" tarafından okunabilir mi? Her bir çizgiden geçmek istemiyorum.

LINQID:1;'dan başlayıp ENDCARD: ile bitebilir mi? Gittiğiniz İşte

string[] lines = System.IO.File.ReadAllLines(SomeFilePath); 

//Cleaning up the text file of unwanted text 
var cleanedUpLines = from line in lines 
        where !line.StartsWith("FIELD1") 
        && !line.StartsWith("FIELD5") 
        && !line.StartsWith("FIELD8") 
        select line.Split(':'); 

//Here i want to LINQtoText "part" by "part" 

//This i do not want to do!!! 
foreach (string[] line in cleanedUpLines) 
{ 
} 

cevap

12

:

Bunun nedeni i her "kısmı" için object oluşturmak istediğiniz olmasıdır

...

aklımda böyle bir şey vardı

static void Main() 
{ 
    foreach(var part in ReadParts("Raw.txt")) 
    { // all the fields for the part are available; I'm just showing 
     // one of them for illustration 
     Console.WriteLine(part["ID"]); 
    } 
} 

static IEnumerable<IDictionary<string,string>> ReadParts(string path) 
{ 
    using(var reader = File.OpenText(path)) 
    { 
     var current = new Dictionary<string, string>(); 
     string line; 
     while((line = reader.ReadLine()) != null) 
     { 
      if(string.IsNullOrWhiteSpace(line)) continue; 
      if(line.StartsWith("ENDCARD:")) 
      { 
       yield return current; 
       current = new Dictionary<string, string>(); 
      } else 
      { 
       var parts = line.Split(':'); 
       current[parts[0].Trim()] = parts[1].Trim().TrimEnd(';'); 
      } 
     } 
     if (current.Count > 0) yield return current; 
    } 
} 

Bunun anlamı şudur: bir yineleyici bloğu oluşturmak (yinelenen verileri okur ve "döndüren bir durum makinesi; tüm dosyayı bir seferde okumaz) satırları tarar; Bir kartın sonu ise, kart "verilmiş"; aksi halde verileri depolamak için bir sözlüke ekler.

Not: Verileri temsil eden kendi class kendinize sahipseniz, değerleri ada göre ayarlamak için yansıma veya FastMember gibi bir şey kullanabilirsiniz.

Bu LINQ'yi doğrudan kullanmaz; Eğer LINQ ile bu tüketen böylece ancak, olarak LINQ Nesnelerin yapı taşı olan bir enumerable diziyi, uygulanmaktadır yani

var data = ReadParts("some.file").Skip(2).First(x => x["ID"] == "123"); 
+0

Vay, bu gerçekten harika. Teşekkürler Marc. =) – Willem

+0

Sadece bu soruyı nasıl bulabileceğinizi, okuyabileceğinizi ve 10'ar dakika içinde (15) tamamıyla nasıl bu kadar temiz ve özlü bir cevapla cevaplayabileceğinizi merak ediyorum. – Oliver

+0

@Oliver bir çok LINQ yapmanın nezaketiyle mi? –

İlgili konular