【问题标题】:Read txt file in C#在 C# 中读取 txt 文件
【发布时间】:2011-11-02 13:53:28
【问题描述】:

我有一个包含以下数据的 txt 文件

(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)

转到行尾,或用: 分割行并取数组的第二个元素。

我觉得好吗?或者我怎样才能提高性能?

【问题讨论】:

  • 你自己试过吗?看起来很简单的任务
  • 列是固定宽度、制表符分隔还是: 分隔?

标签: c# text file-management


【解决方案1】:

您的方法听起来很明智。用“:”分割看起来是一个合理的想法。

这种类型的字符串处理将非常快——而且比将结果数据记录写入磁盘或数据库要快得多,因此效率可能不应该成为问题。

【讨论】:

    【解决方案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();
            }    
        }
    }
    

    【讨论】:

      【解决方案3】:

      这个小方法应该可以解决大部分问题。 :) 它在行上循环(你必须调整循环并用文本阅读器替换它)

      将所有内容放入患者列表中。

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

      【讨论】:

      • 还注意到我没有添加代码来查看是否有重复或数据太少的人(如果可能发生)。
      【解决方案4】:

      您甚至可以在拆分之前检查您的线路是否包含 (0010,0010) 或(4 位数字后跟 4 位数字)。如果检测到,您可以拆分为字符串数组、修剪空格并填充表格行。您可以使用以下表达式查找 (0010,0010)

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

      【讨论】:

        【解决方案5】:

        这似乎是一种合理的方法。在它成为问题之前,我不会担心性能。

        为了论证,我们假设您有 100,000 个。首先编写一些工作代码,然后使用System.Diagnostics.Stopwatch 计算 100 需要多长时间。找到流程中运行时间最长的部分,并尝试缩短它。可能是(我还没有尝试过)逐行读取文件。您可以尝试一口气读取文件,然后将其拆分为换行符。使用处理器的所有内核并行运行它们可能会更好。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-01-24
          • 2017-08-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多