2017-08-25 8 views
0

私は異なるディレクトリ構造/データを持つ3つの異なるカテゴリ(ファイルA、ファイルB &ファイルC)に属する複数のCSVファイルを私のディレクトリに持っています。私はSmartXLSライブラリを使用してコンソールアプリケーションを作成しています。これは新しいファイル(ファイルZと言う)を読み込み、それが属するカテゴリ(A/B/C)を教えてくれます。C#を使用してファイルリストからCSVファイルを対応するカテゴリに検証する方法は?

ディレクトリから複数のファイルを読み取ることができますが、ファイルを検証するロジックを書き込めません。親切に、これで私を助けてください。

ファイル形式: ファイルA:使用日、製品名、ユーザーID、使用されるトークン。 ファイルB:理由、月、調整日、トランザクションID、調整されたトークン、
製品名、コメントが追加されました。 ファイルC:使用日、製品名、製品バージョン、ユーザーID、マシン名、 サーバー名、使用されたトークン、使用された時間。

機能:

public void ValidateData() 
     { 
      int count = 0; 

      Tokens = new List<Token>(); 

      var files = Directory.EnumerateFiles(@"C:\Projects", "*.csv"); 

      foreach (string file in files) 
      { 
       using (FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read)) 
       { 
        SmartXLS.WorkBook WB = new WorkBook(); 
        WB.readCSV(file); 

        DataTable dt = WB.ExportDataTable(); 
        string dtSTR; 
        DataRow dr; 

        for (int i = 1; i < dt.Rows.Count; i++) 
        { 
         dr = dt.Rows[i]; 

         try 
         { 
          dtSTR = dr[0].ToString(); 
          if (string.IsNullOrEmpty(dtSTR)) continue; 

          var tkn = new Token(); 
          tkn.Usagedate = ParseDateTime(dtSTR); 
          tkn.Product_name = dr[1].ToString(); 
          tkn.Product_Version = dr[2].ToString(); 
          tkn.Userid = dr[3].ToString(); 


          Tokens.Add(tkn); 
          count++; 

          Console.WriteLine("Read : " + count); 

          Console.WriteLine(" Reading : " + tkn.Usagedate + "," + tkn.Product_name + "," + tkn.Product_Version + "," + tkn.Userid); 

         } 

         catch (Exception ex) 
         { 

         } 

        } 
       } 

      } 
     } 
+0

_異なる構造の列/データ。 – Sach

+0

私は写真を添付し​​ようとしましたが、何らかの理由で私を許していませんでした。ここで が構造体である: ファイルA:使用日付、製品名、ユーザーID、トークンは ファイルBを使用しました。理由、月、\t調整日付、トランザクションID、調整トークン、\t製品名は、追加 ファイルのコメントC:使用日、製品名、製品バージョン、ユーザーID、マシン名、サーバー名、使用されたトークン、使用された時間。 上記は、3つのファイルの昏睡区切りの列見出しです。@Sach – Rck7

+0

元の投稿をこの情報で更新してください。 – Sach

答えて

1

これらは、単純なの.csvファイルであり、あなたはちょうどそれらを分類する必要がある場合は、あなたがusingブロック内のほとんどすべてそのロジックのをスキップして、単純なテキストとしてファイルを扱うことができ、これはおそらくより効率的であることがわかります。

あなたはその違いがフォーマットには言及していないので、私は推測の余地が残っています。カテゴリごとに異なる数の列がありますか?その場合は、行の1つを選択し、String.Splitを使用して文字列配列(列ごとに1つの文字列)を作成し、配列の長さを使用してその列の数を判断します。 [0]それだろう、彼らは同じ数の列を持っていますが、最初の列の情報が異なる場合は、あなたが列について何かを確認するようにif文を変更することができ

public void ValidateData() 
{ 
    var files = Directory.EnumerateFiles(@"C:\Projects", "*.csv"); 

    foreach (string file in files) 
    { 
     // get a string array with one string per row 
     string[] fileRows = File.ReadAllLines(file); 

     foreach (string row in fileRows) 
     { 
      // ignore blank lines 
      if (row.Trim() != "") 
      { 
       char[] splitOn = new char[] {','}; // if the csv files use comma as a delimiter 
       string[] columns = row.Split(splitOn); // this splits the row into one string per column 

       int numberOfCols = columns.Length; // this is how many columns you have 

       // use this info to determine the type of file. 
       if (numberOfCols == 4) 
       { 
        Debug.WriteLine("This is category A"); 
       } 
       else if (numberOfCols == 5) 
       { 
        Debug.WriteLine("This is category B"); 
       } 
       else if (numberOfCols == 7) 
       { 
        Debug.WriteLine("This is category C"); 
       } 
       else 
       { 
        Debug.WriteLine("Unexpected file type."); 
       } 

       break; // end the loop now - we've already done what we needed to do. 
      } 
     } 

    } 
} 

:それはこのようになりますたとえば、ファイルAの最初の列に日付があると言うと、DateTime.TryParse(columns[0], out var date)を使用すると、最初の列に日付が含まれている場合はtrueを返し、そうでない場合はfalseを返すことができます。ファイルタイプの違いについて具体的に分かっているなら、具体的な助けをする方が簡単でしょう。

編集:上記の例では、変数rowは空白ではない最初のデータ行を表します。 CSVファイルの最初の行に列のタイトルが含まれている場合は、文字列をチェックして列のタイトルを確認してください:

public void ValidateData() 
{ 
    var files = Directory.EnumerateFiles(@"C:\Projects", "*.csv"); 

    foreach (string file in files) 
    { 
     // get a string array with one string per row 
     string[] fileRows = File.ReadAllLines(file); 

     foreach (string row in fileRows) 
     { 
      // ignore blank lines 
      if (row.Trim() != "") 
      { 
       char[] splitOn = new char[] { ',' }; // if the csv files use comma as a delimiter 
       string[] columns = row.Split(splitOn); // this splits the row into one string per column 

       // the third column (columns[2]) is the first that is different for all file types. 
       if (columns[2] == "User ID") 
       { 
        Debug.WriteLine("This is file A"); 
       } 
       else if (columns[2] == "Adjustment Date") 
       { 
        Debug.WriteLine("This is file B"); 
       } 
       else if (columns[2] == "Product Version") 
       { 
        Debug.WriteLine("This is file C"); 
       } 
       else 
       { 
        Debug.WriteLine("Unknown file type."); 
       } 

       break; // end the loop now - we've already done what we needed to do. 
      } 
     } 

    } 
} 
+0

OPの相違情報を更新した後に私は答えを投稿しようとしていましたが、あなたはそれを打ちました。これはかなりです。いいえ簡潔なコードはありません。 – Sach

+0

ありがとうございます。はい、私は彼が詳細を投稿する前に始めましたが、これは彼の明確化に基づいて、OPにかなり近いソリューションを得られるはずです。 –

+0

@ElementalPeteありがとうございます。列数(列数なし)の代わりに列名を使用してデータを検証する方法を教えてください。将来、列数が変化する可能性があるからです。 – Rck7

関連する問題