2011-11-02 76 views
1

txt文件,我有一個txt文件,用下面的數據閱讀C#

(0010,0010) : Patient's Name    : LANE^LOIS^^^ 

(0010,0020) : Patient ID     : AM-0053 

(0010,0030) : Patient's Birth Date   : 4/15/1982 

(0010,0040) : Patient's Sex     : F 

我必須逐行讀取內容線和創建數據表具有以下細節 患者姓名,患者ID,患者出生日期,患者性別。常數(如(0010,0010))將不會更改。它代表病人的姓名。你能否給我一下任務背後的邏輯。我有這麼多,一行

讀線

取前11個字符,並檢查它是否是(0010,0010)

轉到行尾,或由:分割線,走數組的第二個元素。

我覺得好嗎?或者我該如何提高性能?

+4

你有沒有試過自己做這個?看起來像一個非常簡單的任務 – sll

+0

列是固定寬度,製表符分隔還是':'分隔? –

回答

1

這個小方法應該可以解決大多數問題。 :)它遍佈線(你將不得不調整循環,並用文本閱讀器替換它)

將所有內容放在患者列表中。

void Main() 
{ 
    var input = @"(0010,0010) : Patient's Name    : LANE^LOIS^^^ 
    (0010,0020) : Patient ID     : AM-0053 
    (0010,0030) : Patient's Birth Date   : 4/15/1982 
    (0010,0040) : Patient's Sex     : F 
    (0010,0010) : Patient's Name    : LANE^LOIS^^^ 
    (0010,0020) : Patient ID     : AM-0053 
    (0010,0030) : Patient's Birth Date   : 4/15/1982 
    (0010,0040) : Patient's Sex     : F 
    (0010,0010) : Patient's Name    : LANE^LOIS^^^ 
    (0010,0020) : Patient ID     : AM-0053 
    (0010,0030) : Patient's Birth Date   : 4/15/1982 
    (0010,0040) : Patient's Sex     : F"; 
    List<Patient> patients = new List<Patient>(); 

    Patient p = null; 
    foreach(var line in input.Split(new[] {'\n'})) 
    { 
     var value = line.Split(new[] { ':' }, StringSplitOptions.RemoveEmptyEntries).Last().Trim(); 
     if(line.Trim().StartsWith("(0010,0010)")) 
     { 
      if(p != null) 
       patients.Add(p); 
      p = new Patient(); 
      p.Name = value; 
     } 
     else if(line.Trim().StartsWith("(0010,0020)")) 
     { 
      p.ID = value; 
     } 
     else if(line.Trim().StartsWith("(0010,0030)")) 
     { 
      DateTime birthDate; 
      if(DateTime.TryParse(value, out birthDate)) 
       p.BirthDate = birthDate; 
     } 
     else if(line.Trim().StartsWith("(0010,0040)")) 
     { 
      p.Sex = value.ToCharArray()[0]; 
     } 
    } 
    if(p != null) 
     patients.Add(p); 
} 

public class Patient 
{ 
    public string Name { get; set; } 
    public string ID { get; set; } 
    public DateTime? BirthDate { get; set; } 
    public char Sex { get; set; } 
} 
+0

也注意到我沒有添加代碼來查看是否有重複或數據太少的人(如果可能發生的話)。 – NoLifeKing

2

你的方法聽起來很合理。按「:」分割看起來是一個合理的想法。

這種類型的字符串處理將非常快速 - 比將結果數據記錄寫入磁盤或數據庫要快得多,所以效率可能不應該成爲問題。

1

如果分割線包含(0010,0010)或(4個digigts後跟另一個4個數字),您甚至可以在分割之前檢查您的線路。如果檢測到,您可以拆分爲一個字符串數組,修剪空格並填充您的表格行。您可以使用以下表達式來查找(0010,0010)

Regex.IsMatch("line string here...", "[(]{1}[0-9]{4},{1}[0-9]{4}[)]{1}") // should be true if found 
1

這似乎是一種合理的方法。在成爲問題之前,我不會擔心表現。

爲了論證的緣故,假設您有10萬個這樣的參數。先寫一些工作代碼,然後使用System.Diagnostics.Stopwatch來計算100需要多長時間。找出流程中運行時間最長的部分,並嘗試縮短流程。它可能是(我沒有嘗試過)逐行閱讀文件。您可以嘗試一次讀取文件,並將其拆分爲換行符。使用處理器的所有核心並行運行它們可能會更好。

2

除非您知道存在問題,否則不要擔心性能問題,但通常情況下,如果您可以避免出現多餘的內存分配,則對您有利。因此,如果所有你需要的是最後一部分,你可以在字符串上使用StartsWith(),所以你不必創建一個子字符串,以後將被垃圾收集,那麼你可以使用LastIndexOf()找到最後一部分的開始,只是子字符串餘。

while((line = Console.ReadLine()) != null) 
{ 
    if (line.StartsWith("0010,0010")) 
    { 
     var pos = line.LastIndexOf(':'); 

     if (pos != -1) 
     { 
      // do whatever with part 
      var part = line.SubString(pos+1).Trim(); 
     }  
    } 
} 
+0

+1 for'line.StartsWith' – Rauf