我有一个C#控制台应用程序,它可以获取目录中的所有文件。以下面的文件名为例,假设我有3个字符串,ref,year1,year2,我怎么能说:
文件名:31596_2015-06-30.pdf
给我所有文件名包含ref的文件和文件名包含年份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 :(得分: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;
}
}
通过这样做,你可以放一个简单的 Linq 来获取文件
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 :(得分:2)
假设您的文件名始终采用帖子中的格式, 你首先需要将年份分开。 一种可能的解决方案可能是:
string filenameYear = filename.Split('_')[1].Split('-')[0];
然后您可以在if条件中使用此字符串来询问所有三种情况:
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);
如果sourceDir
和targetDir
最后没有\
或者开头是filename
。这会崩溃。
你可以使用
File.Copy(Path.Combine(sourceDir,filename), Path.combine(targetDir, filename);
避免问题
PS。你应该避免使用ref
作为C#中变量的名称。
它保留为keyword
答案 2 :(得分: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);
}