试图用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

试图用linq查询同一文件夹中的许多文本文件

以下内容:

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(',');
通过创建两个相当简单的扩展方法,您的问题变成了一个高度可读的语句。