2017-11-20 7 views
0

は、次のコンソールアプリケーションを使用して:ログファイルを解析し、ファイルへの書き込み、その後、静かに停止を書き込み、入力ファイルのキューが反復を続け

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Linq; 
using System.Text; 
using System.Configuration; 

namespace ConsoleApp1 
{ 
    class Program 
    { 
     static StringBuilder sBuilder = new StringBuilder(); 
     static StreamWriter file; 
     static void Main(string[] args) 
     { 
      try 
      { 
       using (file = new StreamWriter(ConfigurationManager.AppSettings["outFile"], true)) 
       { 
        ProcessDirectory(ConfigurationManager.AppSettings["inDir"]); 

       } 

      } 
      catch (Exception ex) 
      { 
       Console.WriteLine(ex.Message); 
       File.WriteAllText(ConfigurationManager.AppSettings["logFile"], ex.Message); 
       throw; 
      } 

     } 
     public static void ProcessDirectory(string targetDirectory) 
     { 
      string[] fileEntries = Directory.GetFiles(targetDirectory); 
      foreach (string fileName in fileEntries) 
       ProcessFile(fileName); 

      string[] subdirectoryEntries = Directory.GetDirectories(targetDirectory); 
      foreach (string subdirectory in subdirectoryEntries) 
       ProcessDirectory(subdirectory); 
     } 

     public static void ProcessFile(string path) 
     { 

      var lines = File.ReadAllLines(path); 

      var filtered = lines 
      .Where(x => x[0] != '#') 
      .Select(line => line.Split(' ')) 
      .Where(fields => 
       fields[8] != '-' // and other filtering 
       ) 
      .Select(f => string.Join(" ", new string[] { 
        f[0], 
        f[8].ToLower().Replace("some_value",""), 
        ((some_contextual_condition || another_contextual_condition)? "1" : "0") 
      } 
      )) 
      .Distinct(); 

      var sBuilder = new StringBuilder(); 

      filtered 
       .ToList() 
       .ForEach(f => 
       { 
        sBuilder.AppendLine(f); 
       }); 

      file.Write(sBuilder.ToString()); 
     } 
    } 
} 

入力の約3500のファイルが340 GB単位の合計があります。 約400のファイルと約200の書き込み操作を処理した後、出力ファイルには何も書き込まれません。

私は、静的なクラスプロパティとして、またはProcessFileメソッドでローカルスコープの変数としてStringBuilderを使用して、行ごとに記述しようとしています。

実行中のコンソールアプリケーションで添付されたイメージ。ファイル380が処理されるまでに、出力ファイルのサイズは〜まで増加しなくなりました。試してみてください...すべてのメインメソッドのコンテンツを埋め込むことは何も捕らえません。

enter image description here

+0

@Evk、これは私の第nのアプローチです。私は各繰り返しの後にフィルタリングされた値を書きました(最大1.8MB)。 –

+0

そして、現在の実装の最後にすべてが書かれていれば、何も400ファイルの後に出力するよう書かれていないことをどうお知りになりますか?それはStreamWriterを使った別のアプローチですか?デバッガの下で実行して、正確にどこがハングしているのか確認しましたか? – Evk

+0

出力するように書き込まれるバイト数と行数を書きました。しばらくしてから〜15分後に、これらのカウンタは増加を停止します。しかし、私はまだファイルがコンソール出力で取得されていることがわかります。 –

答えて

1

私に飛び出し最初の事はあなたが何のtry-catchブロックを持っていないということです。アプリケーションには、例外の処理方法や報告方法がありません。

読み取りと書き込みのコードの周りにtry-catchブロックを追加し、トラブルシューティングできるようにログに例外を送信します。

+0

例外は発生しません –

+0

あなたはどのように知っていますか? try/catchを使用しない場合、例外は*コンソールにバブルアップする可能性がありますが、必ずしもそうではありません。 –

+0

メモリ制限が発生している可能性があります。また、プロセスをチャンクに分割し、定期的にメモリをフラッシュする必要があります。仕事が確実に完了するまで、仕事を小さな塊に分割してください。 –

1

巨大なStringBuilderを最初に構築するのではなく、それぞれを処理した後に出力ファイルに書き込もうとしましたか?それは助けても、役に立たないかもしれません。私はまた、EnumerateFilesReadLinesに切り替えたare better for reading large files

class Program 
{ 
    static void Main() 
    { 
     var targetDir = ConfigurationManager.AppSettings["inDir"]; 
     var outputFile = ConfigurationManager.AppSettings["outFile"]; 

     foreach (var fileName in Directory.EnumerateFiles(targetDir, "*", 
      SearchOption.AllDirectories)) 
     { 
      ProcessFile(fileName, outputFile); 
     } 
    } 

    public static void ProcessFile(string inputFile, string outputFile) 
    { 
     var lines = File.ReadLines(inputFile) 
      .Where(x => x[0] != '#') 
      .Select(line => line.Split(' ')) 
      .Where(fields => 
       fields[8] != "-" // and other filtering 
      ) 
      .Select(f => string.Join(
       " ", f[0], f[8].ToLower().Replace("some_value", ""), 
       true || false ? "1" : "0")) 
      .Distinct(); 

     File.AppendAllLines(outputFile, lines); 
    } 
} 
+0

それは本当に私の最初の試みでした。 File.ReadAllLinesおよびFile.AppendAllLinesを使用します。 –

+0

ええ、どれくらいの違いがあるかはわかりません。しかし、 'StringBuilder'を使う代わりに(' ProcessFile() 'で)行を書くのはどうでしょうか?何か違いはありますか? –

+0

いいえ、違いはありませんが、私はこの方法にも行きましたが、これはディスクの使用により遅くなります。 –

0

9のWFE。 1番目のWFEには、IISログ構造で15の列がありました。次の8人のWFEは3列目をスキップしていました。

素敵なことに、SPの管理者はうまくやった!

関連する問題