试图用linq查询同一文件夹中的许多文本文件
本文关键字:许多 文本 文件 文件夹 linq 查询 | 更新日期: 2023-09-27 18:17:11
我需要搜索包含csv文件的文件夹。我感兴趣的唱片有3个领域:Rec, Country和Year。我的工作是搜索这些文件,看看是否有任何文件有超过一年的记录。下面的代码我到目前为止:
//从文件夹中获取每个单独的文件。
string startFolder = @"C:'MyFileFolder'";
System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(startFolder);
IEnumerable<System.IO.FileInfo> fileList = dir.GetFiles("*.*",
System.IO.SearchOption.AllDirectories);
var queryMatchingFiles =
from file in fileList
where (file.Extension == ".dat" || file.Extension == ".csv")
select file;
然后我想出了这个代码从每个文件读取年字段,并找到那些年计数大于1(计数部分未成功实现)
public void GetFileData(string filesname, char sep)
{
using (StreamReader reader = new StreamReader(filesname))
{
var recs = (from line in reader.Lines(sep.ToString())
let parts = line.Split(sep)
select parts[2]);
}
示例文件下面的:
REC,IE,2014
REC,DE,2014
REC,FR,2015
现在我正在努力结合这两个想法来解决我的问题在一个单一的查询。查询应该列出记录超过一年的文件。
Thanks in advance
以下内容:
string startFolder = @"C:'MyFileFolder'";
System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(startFolder);
IEnumerable<System.IO.FileInfo> fileList = dir.GetFiles("*.*",
System.IO.SearchOption.AllDirectories);
var fileData =
from file in fileList
where (file.Extension == ".dat" || file.Extension == ".csv")
select GetFileData(file, ',')
;
public string GetFileData(string filesname, char sep)
{
using (StreamReader reader = new StreamReader(filesname))
{
var recs = (from line in reader.Lines(sep.ToString())
let parts = line.Split(sep)
select parts[2]);
var multipleyears = recs.Distinct().Count();
if(multipleyears > 1)
return filename;
}
}
不是在我的开发机器上,所以这可能不会编译"原样",但这里有一个方向
var lines = // file.readalllines();
var years = from line in lines
let parts = line.Split(new [] {','})
select parts[2]);
var distinct_years = years.Distinct();
if (distinct_years >1 )
// this file has several years
"我的工作是搜索文件,看看是否有任何文件有记录不止一年。"
这指定了您想要一个布尔结果,该结果表示是否有任何文件具有这些记录。
为了好玩,我将它扩展一点:
我的工作是收集任何记录都超过一年的文件。
你就快到了。让我们首先用文件中的记录声明一个类:
public class MyRecord
{
public string Rec { get; set; }
public string CountryCode { get; set; }
public int Year { get; set; }
}
我将为类FileInfo创建一个扩展方法,该方法将读取文件并返回其中的MyRecords序列。
有关扩展方法,请参见MSDN扩展方法(c#编程指南)
public static class FileInfoExtension
{
public static IEnumerable<MyRecord> ReadMyRecords(this FileInfo file, char separator)
{
var records = new List<MyRecord>();
using (var reader = new StreamReader(file.FullName))
{
var lineToProcess = reader.ReadLine();
while (lineToProcess != null)
{
var splitLines = lineToProcess.Split(new char[] { separator }, 3);
if (splitLines.Length < 3) throw new InvalidDataException();
var record = new MyRecord()
{
Rec = splitLines[0],
CountryCode = splitLines[1],
Year = Int32.Parse(splitLines[2]),
};
records.Add(record);
lineToProcess = reader.ReadLine();
}
}
return records;
}
}
我可以用字符串代替FileInfo,但恕我直言,字符串与文件名完全不同。
在上面的代码之后,你可以写如下:
string startFolder = @"C:'MyFileFolder'";
var directoryInfo = new DirectoryInfo(startFolder);
var allFiles = directoryInfo.EnumerateFiles("*.*", SearchOption.AllDirectories);
var sequenceOfFileRecordCollections = allFiles.ReadMyRecords(',');
现在每个文件中都有MyRecords的序列。您想知道哪些文件有超过一年的时间,让我们向FileInfoExtension类添加另一个扩展方法:
public static bool IsMultiYear(this FileInfo file, char separator)
{
// read the file, only return true if there are any records,
// and if any record has a different year than the first record
var myRecords = file.ReadMyRecords(separator);
if (myRecords.Any())
{
int firstYear = myRecords.First().Year;
return myRecords.Any(record => record.Year != firstYear);
}
else
{
return false;
}
}
超过一年的文件序列为:
allFiles.Where(file => file.IsMultiYear(',');
将所有内容放在一行中:
var allFilesWithMultiYear = new DirectoryInfo(@"C:'MyFileFolder'")
.EnumerateFiles("*.*", SearchOption.AllDirectories)
.Where(file => file.IsMultiYear(',');
通过创建两个相当简单的扩展方法,您的问题变成了一个高度可读的语句。