2011-11-02 69 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