2016-06-20 8 views
4

Cobolシステムで生成されたシーケンシャルファイルを処理するシステムを開発中です。現在、データを取得するためにいくつかの部分文字列を使用してデータ処理を行っていますが、プロセスのいくつかのサブストリングを作成するよりも、ファイル...今ではシーケンシャルファイルの効率的な処理C#

が、私は基本的に行います。

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

ファイルサイズは50メガバイトと150メガバイトの間で変動することがあります... ファイルの小さな例:

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

効率的ですか?コードの実行速度が速いのはなぜですか?あるいは、コードを書く実際のプロセスはより効率的ですか? –

+2

これを試したことはありませんが、これを試してみてください。http://stackoverflow.com/a/20803/1105235 – rpeshkov

+0

正規表現は実際にはじまるまで一時的な文字列を生成しないため、手動で分割するよりも高速です*ロット*あなたが望むマッチを抽出する。これは、大きなファイルを解析する場合、割り当てとガベージコレクションを劇的に減らすため、大きな利点です。また、特定のグループに名前を割り当てることもできます(例: ''(?。{15})(?。{14}) '等 –

答えて

0

私は、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

これはパフォーマンスをまったく損なうものではありません。いずれにせよ、[File.ReadLines](https://msdn.microsoft.com/en-us/library/system.io.file.readlines(v = vs.110).aspx)は、ここでReadFIleと同じです –

+1

@PanagiotisKanavos質問者はアルゴ最適化のみを探していますか? – fahadash

+0

150MBのデータを読むとき、質問はアルゴリズムに関するものではなく、スピードとメモリに関するものです。ところで、最初の文字で索引付けされたRegexオブジェクトの配列/ディクショナリが本当に助けになります。しかし、どんな場合でも、OPはCOBOLファイルの解析を求めています。私はそこに少なくとも1つの図書館があると思う。 –

2

頻繁なディスクは、あなたのコードが遅くなります読み込み大好きです。

MSDNによると、constructor you are usingのバッファサイズは1024バイトです。 異なるコンストラクタを使用して、より大きなバッファサイズを設定:

int bufferSize = 1024 * 128; 

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

C#のように、すべての文字列関数は、新しい文字列を生成し、速度上の安全性を優先。

これらの部分文字列のすべてが必要ですか?そうでない場合は、必要なものを生成してください:

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

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

私の経験では、これは通常、データがストリームリーダーコードに到達する前に、ディスクサブシステムが正常にバッファリングされているため、ほとんど違いがありません。しかし、それは確かに試してみる価値があります。 –

1

一度に1文字ずつファイルを処理するパーサーを作成してみてください。

先日、CSVファイルでこれを行う方法については、「Writing a parser for CSV data」というタイトルの記事を読みましたが、プリンシパルはほとんどのファイルタイプで同じですが、これは、C#とここhttp://www.boyet.com/articles/csvparser.html

+4

フィールドは固定開始位置と固定幅です。 CSVの解析はどこに行われますか? –

+0

CSVは重要なことではありませんが、重要なのはパーサーの使用です。私が参照した記事では、CSVを例として使用して、構文解析の原理を実証しています。 –

+0

あなたはいくつかのオプションの変位/オフセットを使って "sourcefield namea(length)nameb(length)namec(length)を解析する"ことを意味します。 –

1

まず時間を見つけることができますが、私はあなたが

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

のようなものを見て、そしてちょうど[0]の場合のラインで異なる構造体を割り当てたいと思います。あるいは、ナダの隣でC#について知っていると、間違った野球場にいる可能性があり、最終的には内部的に貧しいパフォーマーになる可能性があります。

関連する問題