Читать текстовый файл в C # - PullRequest
1 голос
/ 02 ноября 2011

У меня есть текстовый файл со следующими данными

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

Перейти к концу строки или разбить строку на : и взять второй элемент массива.

Я хорошо думаю? Или как мне улучшить производительность?

Ответы [ 5 ]

2 голосов
/ 02 ноября 2011

Не беспокойтесь о производительности, пока не узнаете, что есть проблема, но в целом, если вы можете избежать избыточного выделения памяти, это в ваших интересах. Таким образом, если вам нужна только последняя часть, вы можете использовать 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();
        }    
    }
}
2 голосов
/ 02 ноября 2011

Ваш подход звучит разумно. Разделение на ":" выглядит разумной идеей.

Обработка строк такого типа будет очень быстрой - и намного быстрее, чем запись результирующей записи данных на диск или в базу данных, поэтому эффективность, вероятно, не должна беспокоить.

1 голос
/ 02 ноября 2011

этот маленький метод должен решить большинство проблем.:) Он зацикливается на строках (вам нужно будет настроить цикл и заменить его на текстовый ридер)

Помещает все в список пациентов.

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; }
}
1 голос
/ 02 ноября 2011

Это похоже на разумный подход. Я не буду беспокоиться о производительности, пока она не станет проблемой.

Ради аргумента, давайте предположим, что у вас есть 100 000 из них. Сначала напишите какой-нибудь рабочий код и используйте System.Diagnostics.Stopwatch для определения времени, которое занимает 100. Найдите самую продолжительную часть процесса и попытайтесь сократить ее. Это может быть (и я не пытался) чтение файла построчно. Вы можете попробовать прочитать файл за один раз и разбить его на символ новой строки. Возможно, было бы лучше запустить их параллельно, используя все ядра вашего процессора.

1 голос
/ 02 ноября 2011

Вы можете проверить свою строку еще до того, как разбить ее, если она содержит (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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...