2016-07-01 14 views
2

ディレクトリ内のすべてのファイルを取得するC#コンソールアプリケーションがあります。一例として、以下のファイル名を取って、私は私が言うことができるか、3列、REF、YEAR1、YEAR2を持っているだろうことを考える:ファイル名の部分文字列に基づいてディレクトリからファイルを取得する - C#

ファイル名:31596_2015-06-30.pdf

を私にファイル名が含まれているすべてのファイルを与えますref ANDファイル名には年1と年2の間の年が含まれていますか?これまで コード:

var files = Directory.EnumerateFiles(sourceDir, "*", SearchOption.TopDirectoryOnly) 
          .Select(Path.GetFileName); 

string start_year = null; 
string end_year = null; 
string ref = null; 

// dr is a sql data reader 
if (dr.HasRows == true) 
{ 
    while (dr.Read()) 
    { 
     start_year = dr.GetString(1).Substring(7, 4); 
     end_year = dr.GetString(2).Substring(7, 4); 
     ref = dr.GetString(3); 

     foreach(string filename in files) 
     { 
      if (filename.Contains(ref)) 
      { 
       File.Copy(sourceDir + filename, targetDir + filename); 
      } 
     } 

     File.Copy(sourceDir + dr.GetString(0), targetDir + dr.GetString(0)); 
    } 
} 
+0

編集を参照してくださいdrはデータレッサーです – DarkW1nter

+3

refはキーワードですので、その変数のより良い名前を見つけることを強くお勧めします – Sorceri

答えて

3

FileData

public class FileData { 
    public bool IsParsed {get; private set; } 

    public String FileName {get; private set; } 

    public DateTime Date {get; private set; } 

    public String Ref {get; private set; } 

    public FileData(String path) { 
    FileName = path; 

    if (String.IsNullOrEmpty(path)) 
     return; 

    int p = path.IndexOf('_'); 

    if (p < 0) 
     return; 

    Ref = path.Substring(0, p); 

    DateTime dt; 

    IsParsed = DateTime.TryParseExact(path.Substring(p + 1), 
     "yyyy-MM-dd", 
     CultureInfo.InvariantCulture, 
     DateTimeStyles.None, 
    out dt); 

    Date = dt; 
    } 
} 

これを行うことにより、あなたは

var files = Directory 
    .EnumerateFiles(sourceDir, "*", SearchOption.TopDirectoryOnly) 
    .Select(file => new FileData(file)) 
    .Where(info => info.IsParsed) 
    .Where(info => String.Equals(info.Ref, myRef)) 
    .Where(info => info.Date.Year >= year1 && info.Date.Year <= year2) 
    .Select(info => info.FileName); 
1

私はこの種のもののためにLINQが好き。読者の価値が常に期待どおりになるという事実を知らない限り、いくつかのバリデーションを実行する必要がありますが、サンプルコードの変更量を最小限に抑えて目標を達成できます。私はクラス、発言権を抽出示唆

var start_year = (DateTime)dr.GetString(1).Substring(7, 4); 
    var end_year = (DateTime)dr.GetString(2).Substring(7, 4); 
    ref = dr.GetString(3); 

    foreach(string filename in files.Where(x => x.StartsWith(ref) 
        && (DateTime)x.Substring(7, 4) >= start_year 
        && (DateTime)x.Substring(7, 4) <= end_year)) 
    { 
     File.Copy(sourceDir + filename, targetDir + filename); 
    } 
2

があると仮定すると、ファイルを取得するために、単純なLINQのを置くことができますあなたのファイル名はあなたの投稿と同じように常にあります。 最初の年を名前から切り離す必要があります。 一つの可能​​な解決策は次のようになります。行の

if (filename.Contains(_ref) && 
    Convert.ToInt32(filenameYear) > Convert.ToInt32(start_year) && 
    Convert.ToInt32(filenameYear) < Convert.ToInt32(end_year)) 
{ 
    // Do what ever you desire 

} 

File.Copy(sourceDir + filename, targetDir + filename); 

もし

string filenameYear = filename.Split('_')[1].Split('-')[0]; 

が、あなたはすべての3例を求めるために、あなたの場合は条件にこの文字列を使用することができますsourceDirおよびtargetDirは、最後に\または最初にfilenameではありません。これはクラッシュします。 あなたは問題

psのを避けるために

File.Copy(Path.Combine(sourceDir,filename), Path.combine(targetDir, filename); 

を使用することができます。 C#の変数の名前としてrefを使用しないでください。 keyword

関連する問題