2016-06-20 29 views
4

Ich entwickle ein System, das sequentielle Dateien verarbeitet, die von Cobol-Systemen erzeugt werden. Zurzeit mache ich die Datenverarbeitung mit mehreren Teilstrings, um die Daten zu erhalten, aber ich frage mich, ob es einen effizienteren Weg gibt bearbeiten Sie die Datei als auf mehr Teil zu machen ...Effiziente Verarbeitung sequentieller Dateien C#

auf jetzt, muß ich im Grunde:

using (var sr = new StreamReader("file.txt")) 
{ 
    String line = ""; 
    while(!sr.EndOfStream) 
    { 
     line = sr.ReadLine(); 
     switch(line[0]) 
     { 
      case '0': 
       processType0(line); 
       break; 
      case '1': 
       processType1(line); 
       break; 
      case '2': 
       processType2(line); 
       break; 
      case '9': 
       processType9(line); 
       break; 
     } 
    } 
} 

private void processType0(string line) 
{ 
    type = line.Substring(0, 15); 
    name = line.Substring(15, 30); 
    //... and more 20 substrings 
} 

private void processType1(string line) 
{ 
    // 45 substrings... 
} 

die Dateigröße zwischen 50 MB und 150 MB ... Ein kleines Beispiel für die Datei kann variieren:

01ARQUIVO01CIVDSUQK  00000000000000999999NAME NAME NAME NAME   892DATAFILE  200616  KY0000853                                                                      000001 
1000000000000000000000000999904202589ESMSS59365  00000010000000000000026171900000000002   0 01000000000001071600000099740150000000001N020516000000000000000000000000000000000000000000000000000000000000009800000000000000909999-AAAAAAAAAAAAAAAAAAAAAAAAA               00000000               000002 
1000000000000000000000000861504202589ENJNS63198  00000010000000000000036171300000000002   0 01000000000001071600000081362920000000001N020516000000000000000000000000000000000000000000000000000000000000009800000000000000909999-BBBBBBBBBBBBBBBBBBBBBBBBBB               00000000               000003 
9                                                                                                   000004 
+5

Effizient? Wie im Code läuft das schneller? Oder der tatsächliche Prozess des Schreibens des Codes ist effizienter? –

+2

Ich habe das nicht selbst versucht, aber versuchen Sie dies http://StackOverflow.com/a/20803/1105235 – rpeshkov

+0

Ein regulärer Ausdruck wird ein * Los * schneller als manuelle Aufteilung sein, weil es keine temporären Zeichenketten erzeugt, bis Sie tatsächlich Extrahiere die gewünschten Matches. Dies ist ein großer Vorteil beim Analysieren großer Dateien, da dadurch Zuordnungen und Speicherbereinigungen drastisch reduziert werden. Sie können auch Namen bestimmten Gruppen zuweisen, zB '" (? . {15}) (? . {14}) 'usw. –

Antwort

0

Ich liebe Linq

IEnumerable<string> ReadFile(string path) 
{ 
using (var reader = new StreamReader(path)) 
    { 
    while (!reader.EndOfStream) 
    { 
    yield return reader.ReadLine(); 
    } 
    } 
} 


void DoThing() 
{ 
    var myMethods = new Action<string>[] 
    { 
     s => 
     { 
      //Process 0    
      type = line.Substring(0, 15); 
      name = line.Substring(15, 30); 
      //... and more 20 substrings 
     }, 
     s => 
     { 
      //Process 1    
      type = line.Substring(0, 15); 
      name = line.Substring(15, 30); 
      //... and more 20 substrings 
     }, 
      //... 

    } 

var actions = ReadFile(@"c:\path\to\file.txt") 
     .Select(line => new Action(() => myMethods[int.Parse(line[0])]())) 
     .ToArray(); 

actions.ForEach(a => a.Invoke()); 
} 
+0

Dies wird die Leistung überhaupt nicht verbessern. In jedem Fall tut [File.ReadLines] (https://msdn.microsoft.com/en-us/library/system.io.file.readlines (v = vs.110) .aspx) das gleiche wie ReadFIle hier –

+1

@PanagiotisKanavos Sucht der Fragesteller nur nach der Algo-Optimierung? – fahadash

+0

Beim Lesen von 150MB Daten geht es nicht um Algorithmen, sondern um Geschwindigkeit und Speicher. Übrigens würde ein Array/Wörterbuch von Regex-Objekten, die durch das erste Zeichen indiziert sind, wirklich helfen. In jedem Fall fragt das OP nach dem Parsen der COBOL-Datei. Ich vermute, es gibt mindestens eine Bibliothek für diese –

2

Frequent Platte liest den Code wird sich verlangsamen.

Laut MSDN beträgt die Puffergröße für constructor you are using 1024 Byte. Stellen Sie eine größere Puffergröße einen anderen Konstruktor:

int bufferSize = 1024 * 128; 

using (var reader = new StreamReader(path, encoding, autoDetectEncoding, bufferSize)) 
{ 
    ... 
} 

C# priorisiert Sicherheit über Geschwindigkeit, so dass alle String-Funktionen erzeugen eine neue Zeichenfolge.

Benötigen Sie wirklich alle dieser Teilstrings? Wenn nicht, dann nur diejenigen, erzeugen Sie brauchen:

private static string GetType(string line) 
{ 
    return line.Substring(0, 15); 
} 

if (needed) 
    type = GetLine(line); 
+0

Meiner Erfahrung nach macht dies normalerweise nur wenig Unterschied, da das Disk-Subsystem normalerweise ziemlich gut gepuffert ist, bevor die Daten überhaupt in den Stream-Reader-Code gelangen. Aber es ist sicherlich einen Versuch wert. –

1

Sie könnten versuchen, einen Parser zu schreiben, die die Datei ein Zeichen in einer Zeit verarbeitet.

Ich lese einen guten Artikel mit dem Titel 'Writing a parser for CSV data' darüber, wie man das mit CSV-Dateien neulich tut, obwohl die Principals für die meisten Dateitypen gleich sind. Dies ist hier zu finden http://www.boyet.com/articles/csvparser.html

+4

Die Felder sind feste Startpositionen und feste Breite. Wo kommt das Parsen einer CSV ins Spiel? –

+0

CSV ist hier nicht das Wichtigste, es ist die Verwendung eines Parsers, der das Wichtigste ist. Der Artikel, auf den ich verwiesen habe, verwendet zufällig CSV als Beispiel, um die Prinzipien des Parsens zu demonstrieren. –

+0

Sie meinen "parse sourcefield namea (length) nameb (length) namec (length) mit einigen optionalen Verschiebungen/Offsets? Am Ende ist das gleiche wie gestartet wurde, nur eine one- (long) -Liner. I bin mir wirklich nicht sicher, wohin du damit gehst, aber du hast Anhänger :-) –

1

Zum ersten Mal mit C#, aber ich glaube, Sie etwas sehen möchten, wie

struct typeOne { 
    fixed byte recordType[1]; 
    fixed byte whatThisFieldIsCalled[10]; 
    fixed byte someOtherFieldName[5]; 
    ... 
} 

und weisen nur unterschiedliche Strukturen für Zeile [0] Fall. Oder, neben Nada über C# zu wissen, dass könnte in der völlig falschen Baseballstadion sein und am Ende ein schlechter Darsteller intern sein.