C# 在C中读取txt文件

C# 在C中读取txt文件,c#,text,file-management,C#,Text,File Management,我有一个包含以下数据的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 我必须逐行阅读内容,并创

我有一个包含以下数据的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、患者出生日期、患者性别。常量eg 00100010将不会更改。它代表病人的名字。你能告诉我这项任务背后的逻辑吗。我有这么多

逐行阅读

获取前11个字符并检查其是否为00100010

Regex.IsMatch("line string here...", "[(]{1}[0-9]{4},{1}[0-9]{4}[)]{1}") // should be true if found
转到行尾,或将行拆分为:并获取数组的第二个元素


我想得好吗?或者如何提高性能?

您的方法听起来很明智。分开:看起来是个合理的想法


这种字符串处理速度非常快,而且比将生成的数据记录写入磁盘或数据库快得多,因此效率可能不值得关注。

您的方法听起来很合理。分开:看起来是个合理的想法


这类字符串处理速度非常快,而且比将结果数据记录写入磁盘或数据库快得多,因此效率可能不应该是一个问题。

如果行包含00100010或4个数字,后跟,和另外4个数字,则可以在拆分行之前检查行。如果检测到,可以将其拆分为字符串数组、修剪空格并填充表行。可以使用以下表达式查找00100010

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

如果行包含00100010或4位数字,后跟、和另外4位数字,则可以在拆分之前检查行。如果检测到,可以将其拆分为字符串数组、修剪空格并填充表行。可以使用以下表达式查找00100010

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

这似乎是一个合理的方法。我不会担心性能,直到它成为一个问题


为了便于讨论,让我们假设你有100000个。首先编写一些工作代码,并使用System.Diagnostics.Stopwatch来计算100所需的时间。找到流程中运行时间最长的部分,并尝试缩短它。可能是这样,我还没有试着逐行读取文件。您可以尝试一次读取文件,并在换行符上拆分它。最好使用处理器的所有内核并行运行它们。

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


为了便于讨论,让我们假设你有100000个。首先编写一些工作代码,并使用System.Diagnostics.Stopwatch来计算100所需的时间。找到流程中运行时间最长的部分,并尝试缩短它。可能是这样,我还没有试着逐行读取文件。您可以尝试一次读取文件,并在换行符上拆分它。使用处理器的所有核心并行运行它们可能更好。

在发现问题之前,不要担心性能问题,但一般来说,如果可以避免过多的内存分配,这对您是有利的。因此,如果您只需要最后一部分,那么您可以使用StartsWith on string,这样您就不必创建稍后将被垃圾收集的子字符串,然后您可以使用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();
        }    
    }
}

在知道存在问题之前,不要担心性能,但一般来说,如果可以避免过多的内存分配,这对您是有利的。因此,如果您只需要最后一部分,那么您可以使用StartsWith on string,这样您就不必创建稍后将被垃圾收集的子字符串,然后您可以使用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();
        }    
    }
}

这个小方法可以解决大多数问题它在行上循环,你必须调整循环并用文本阅读器替换它

把所有的东西都放在病人名单上

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

这个小方法可以解决大多数问题它在行上循环,你必须调整循环并用文本阅读器替换它

把所有的东西都放在病人名单上

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

你自己试过吗?看起来是一个非常简单的任务。列是固定宽度的、制表符分隔的还是:分隔的?您自己试过吗?看起来是一个非常简单的任务,列是固定宽度的、制表符分隔的还是:分隔的?还注意到我没有添加代码以查看是否存在重复项或数据太少的人(如果可能发生)。还注意到我没有添加代码以查看是否存在重复项或数据太少的人(如果可能发生)。