Быстрое чтение и анализ данных - PullRequest
0 голосов
/ 14 декабря 2011

На данный момент я использую этот код, чтобы открыть файл и прочитать его в список и разобрать этот список в string[]:

string CP4DataBase =
    "C:\\Program\\Line Balancer\\FUJI DB\\KTS\\KTS - CP4 - Part Data Base.txt";
CP4DataBaseRTB.LoadFile(CP4DataBase, RichTextBoxStreamType.PlainText);
string[] splitCP4DataBaseLines = CP4DataBaseRTB.Text.Split('\n');
List<string> tempCP4List = new List<string>();
string[] line1CP4Components;

foreach (var line in splitCP4DataBaseLines)
                    tempCP4List.Add(line + Environment.NewLine);

string concattedUnitPart = "";
foreach (var line in tempCP4List)
{
    concattedUnitPart = concattedUnitPart + line;
    line1CP4PartLines++;
}
line1CP4Components = new Regex("\"UNIT\",\"PARTS\"", RegexOptions.Multiline)
                    .Split(concattedUnitPart)
                    .Where(c => !string.IsNullOrEmpty(c)).ToArray();

Мне интересно, есть ли более быстрый способ сделать это. Это только один из файлов, которые я открываю, так что это повторяется минимум 5 раз, чтобы открыть и правильно загрузить списки.

Минимальный размер импортируемого файла сейчас составляет 257 КБ. Самый большой файл - 1803 КБ. Эти файлы будут только увеличиваться с течением времени, так как они используются для имитации базы данных, и пользователь будет постоянно добавлять к ним.

Итак, мой вопрос: есть ли более быстрый способ выполнить весь приведенный выше код?

EDIT:

***CP4***
"UNIT","PARTS"
"BLOCK","HEADER-"
    "NAME","106536"
    "REVISION","0000"
    "DATE","11/09/03"
    "TIME","11:10:11"
    "PMABAR",""
    "COMMENT",""
    "PTPNAME","R160805"
    "CMPNAME","R160805"
"BLOCK","PRTIDDT-"
    "PMAPP",1
    "PMADC",0
    "ComponentQty",180
"BLOCK","PRTFORM-"
    "PTPSZBX",1.60
    "PTPSZBY",0.80
    "PTPMNH",0.25
    "NeedGlue",0
"BLOCK","TOLEINF-"
    "PTPTLBX",0.50
    "PTPTLBY",0.40
    "PTPTLCL",10
    "PTPTLPX",0.30
    "PTPTLPY",0.30
    "PTPTLPQ",30
"BLOCK","ELDT+"     "PGDELSN","PGDELX","PGDELY","PGDELPP","PGDELQ","PGDELP","PGDELW","PGDELL","PGDELWT","PGDELLT","PGDELCT","PGDELR"
    0,0.000,0.000,0,0,0.000,0.000,0.000,0.000,0.000,0.000,0
"BLOCK","VISION-"
    "PTPVIPL",0
    "PTPVILCA",0
    "PTPVILB",0
    "PTPVICVT",10
    "PENVILIT",0
"BLOCK","ENVDT"
    "ELEMENT","CP43ENVDT-"
        "PENNMI",1.0
        "PENNMA",1.0
        "PENNZN",""
        "PENNZT",1.0
        "PENBLM",12
        "PENCRTS",0
        "PENSPD1",100
        "PTPCRDCT",0
        "PENVICT",1
        "PCCCRFT",1
"BLOCK","CARRING-"
    "PTPCRAPO",0
    "PTPCRPCK",0
    "PTPCRPUX",0.00
    "PTPCRPUY",0.00
    "PTPCRRCV",0
"BLOCK","PACKCLS-"
    "FDRTYPE","Emboss"
    "TAPEWIDTH","8mm"
    "FEEDPITCH",4
    "REELDIAMETER",0
    "TAPEDEPTH",0.0
    "DOADVVACUUM",0
    "CHKBEFOREFEED",0
    "TAPEARMLENGTH",0
    "PPCFDPP",0
    "PPCFDEC",4
    "PPCMNPT",30
"UNIT","PARTS"
"BLOCK","HEADER-"
    "NAME","106653"
    "REVISION","0000"
    "DATE","11/09/03"
    "TIME","11:10:42"
    "PMABAR",""
    "COMMENT",""
    "PTPNAME","0603R"
    "CMPNAME","0603R"
"BLOCK","PRTIDDT-"
    "PMAPP",1
    "PMADC",0
    "ComponentQty",18
"BLOCK","PRTFORM-"
    "PTPSZBX",1.60
    "PTPSZBY",0.80
    "PTPMNH",0.23
    "NeedGlue",0
"BLOCK","TOLEINF-"
    "PTPTLBX",0.50
    "PTPTLBY",0.34
    "PTPTLCL",0
    "PTPTLPX",0.60
    "PTPTLPY",0.40
    "PTPTLPQ",30
"BLOCK","ELDT+"     "PGDELSN","PGDELX","PGDELY","PGDELPP","PGDELQ","PGDELP","PGDELW","PGDELL","PGDELWT","PGDELLT","PGDELCT","PGDELR"
    0,0.000,0.000,0,0,0.000,0.000,0.000,0.000,0.000,0.000,0
"BLOCK","VISION-"
    "PTPVIPL",0
    "PTPVILCA",0
    "PTPVILB",0
    "PTPVICVT",10
    "PENVILIT",0
"BLOCK","ENVDT"
    "ELEMENT","CP43ENVDT-"
        "PENNMI",1.0
        "PENNMA",1.0
        "PENNZN",""
        "PENNZT",1.0
        "PENBLM",12
        "PENCRTS",0
        "PENSPD1",80
        "PTPCRDCT",0
        "PENVICT",1
        "PCCCRFT",1
"BLOCK","CARRING-"
    "PTPCRAPO",0
    "PTPCRPCK",0
    "PTPCRPUX",0.00
    "PTPCRPUY",0.00
    "PTPCRRCV",0
"BLOCK","PACKCLS-"
    "FDRTYPE","Emboss"
    "TAPEWIDTH","8mm"
    "FEEDPITCH",4
    "REELDIAMETER",0
    "TAPEDEPTH",0.0
    "DOADVVACUUM",0
    "CHKBEFOREFEED",0
    "TAPEARMLENGTH",0
    "PPCFDPP",0
    "PPCFDEC",4
    "PPCMNPT",30

... файл будет продолжаться и продолжаться .. и будет только увеличиваться.

REGEX помещает каждый «ЧАСТИ ЕДИНИЦЫ» и следующий код до СЛЕДУЮЩИХ «ЧАСТЕЙ ЕДИНИЦЫ» в строку []. После этого я проверяю каждую строку [], чтобы увидеть, существует ли раздел «ИМЯ» в другом списке. Если он существует, я вывожу «ЧАСТИ ЕДИНИЦЫ» в конце текстового файла.

Ответы [ 3 ]

1 голос
/ 14 декабря 2011

Вы можете получить тот же список вывода 'line1CP4Components', используя следующее:

Regex StripEmptyLines = new Regex(@"^\s*$", RegexOptions.Multiline);
Regex UnitPartsMatch = new Regex(@"(?<=\n)""UNIT"",""PARTS"".*?(?=(?:\n""UNIT"",""PARTS"")|$)", RegexOptions.Singleline);

string CP4DataBase =
"C:\\Program\\Line Balancer\\FUJI DB\\KTS\\KTS - CP4 - Part Data Base.txt";
CP4DataBaseRTB.LoadFile(CP4DataBase, RichTextBoxStreamType.PlainText);

List<string> line1CP4Components = new List<string>(
    UnitPartsMatch.Matches(StripEmptyLines.Replace(CP4DataBaseRTB.Text, ""))
        .OfType<Match>()
        .Select(m => m.Value)
    );

return line1CP4Components.ToArray();

Вы можете игнорировать использование StripEmptyLines, но ваш оригинальный код делает это через Where(c => !string.IsNullOrEmpty(c)). Кроме того, ваш оригинальный код вызывает дублирование части '\ r' из пары "\ r \ n" новой строки / перевода строки. Я предположил, что это был несчастный случай, а не преднамеренный?

Также вы, похоже, не используете значение в 'line1CP4PartLines', поэтому я пропустил создание значения. Это было на первый взгляд несовместимо с пропуском пустых строк позже, поэтому я думаю, вы не зависите от этого. Если вам нужно это значение, простое регулярное выражение может сказать вам, сколько новых строк в строке:

int linecount = new Regex("^", RegexOptions.Multiline).Matches(CP4DataBaseRTB.Text).Count;
1 голос
/ 14 декабря 2011

Этот бит является потенциальным фактором снижения производительности:

string concattedUnitPart = "";
foreach (var line in tempCP4List)
{
    concattedUnitPart = concattedUnitPart + line;
    line1CP4PartLines++;
}

(см. в этой статье , почему.) Используйте StringBuilder для повторной конкатенации:

// No need to use tempCP4List at all
StringBuilder builder = new StringBuilder();
foreach (var line in splitCP4DataBaseLines)
{
    concattedUnitPart.AppendLine(line);
    line1CP4PartLines++;
}

Или даже просто:

string concattedUnitPart = string.Join(Environment.NewLine,
                                       splitCP4DataBaseLines);

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

0 голосов
/ 14 декабря 2011

// пример того, как будет выглядеть ваш код

 string CP4DataBase = "C:\\Program\\Line Balancer\\FUJI DB\\KTS\\KTS - CP4 - Part Data Base.txt"; 
List<string> Cp4DataList =  new List<string>(File.ReadAllLines(CP4DataBase);
//or create a Dictionary<int,string[]> object

    string strData = string.Empty;//hold the line item data which is read in line by line
    string[] strStockListRecord = null;//string array that holds information from the TFE_Stock.txt file
    Dictionary<int, string[]> dctStockListRecords = null; //dictionary object that will hold the KeyValuePair of text file contents in a DictList
    List<string> lstStockListRecord = null;//Generic list that will store all the lines from the .prnfile being processed
    if (File.Exists(strExtraLoadFileLoc + strFileName))
    {
        try
        {
            lstStockListRecord = new List<string>();
            List<string> lstStrLinesStockRecord = new List<string>(File.ReadAllLines(strExtraLoadFileLoc + strFileName));
            dctStockListRecords = new Dictionary<int, string[]>(lstStrLinesStockRecord.Count());
            int intLineCount = 0;
            foreach (string strLineSplit in lstStrLinesStockRecord)
            {
                lstStockListRecord.Add(strLineSplit);
                dctStockListRecords.Add(intLineCount, lstStockListRecord.ToArray());
                lstStockListRecord.Clear();
                intLineCount++;
            }//foreach (string strlineSplit in lstStrLinesStockRecord)
            lstStrLinesStockRecord.Clear();
            lstStrLinesStockRecord = null;
            lstStockListRecord.Clear();
            lstStockListRecord = null;

//Alter the code to fit what you are doing.. 
...