linq 如何合并多个Directory.EnumerateFiles与多个搜索条件结合使用

kjthegm6  于 2023-07-31  发布在  其他
关注(0)|答案(2)|浏览(128)

我有包含产品文件的目录。请求是获取特定名称的最新文件,并在WebAPI中返回它们。
我正在执行多个Directory.EnumerateFiles以获取一组匹配的文件。我的代码工作,但我想知道是否有一个更有效的方法来完成这一点,使用第一和级联选项。
最终目标是获得符合当前条件的最新3个文件的列表
当前代码(工作):

string orderNum = "123465";

string[] s1 = Directory.EnumerateFiles(pathSetting, "*" + orderNum+ "*.txt", SearchOption.AllDirectories)
                       .Where(name => name.Contains("red") && !name.StartsWith("H"))
                       .OrderByDescending(file => new FileInfo(file).LastWriteTime)
                       .ToArray();

string[] s2 = Directory.EnumerateFiles(pathSetting, "*" + orderNum+ "*.txt", SearchOption.AllDirectories)
                       .Where(name => name.Contains("red") && name.StartsWith("H"))
                       .OrderByDescending(file => new FileInfo(file).LastWriteTime)
                       .ToArray();

string[] s3 = Directory.EnumerateFiles(pathSetting, "*" + orderNum+ "*.txt", SearchOption.AllDirectories)
                       .Where(name => name.Contains("blue") && !name.StartsWith("H"))
                       .OrderByDescending(file => new FileInfo(file).LastWriteTime)
                       .ToArray();

int sourceArrayLength = (s1.Length > 0 ? 1 : 0) +
                        (s2.Length > 0 ? 1 : 0) +
                        (s3.Length > 0 ? 1 : 0);

string[] sourceFiles = new string[sourceArrayLength];

if (s1.Length > 0)
{
  sourceFiles[arrayCount] = s1[0];
  arrayCount++;
}

if (s2.Length > 0)
{
  sourceFiles[arrayCount] = s2[0];
  arrayCount++;
}

if (s3.Length > 0)
{
  sourceFiles[arrayCount] = s3[0];
  arrayCount++;
}

// perform action on the files

字符串
我尝试了这样的事情(失败):

string[] sFull = Directory.EnumerateFiles(pathSetting, "*" + orderNum+ "*.txt", SearchOption.AllDirectories)
                          .First(name => name.Contains("red") && name.StartsWith("H"))
                          .OrderByDescending(file => new FileInfo(file).LastWriteTime)
         .Concat(Directory.EnumerateFiles(pathSetting, "*" + esoi + "*.txt", SearchOption.AllDirectories)
                          .First(name => name.Contains("red") && !name.StartsWith("H"))
                          .OrderByDescending(file => new FileInfo(file).LastWriteTime))
         .Concat(Directory.EnumerateFiles(pathSetting, "*" + esoi + "*.txt", SearchOption.AllDirectories)
                          .First(name => name.Contains("blue") && name.StartsWith("H"))
                          .OrderByDescending(file => new FileInfo(file).LastWriteTime))
         .ToArray();


这里的问题是我不能按降序排序。我也试过Directory.GetFiles,但也有局限性。
提前感谢您的建议。

fcg9iug3

fcg9iug31#

我认为您可以通过使用对Directory.EnumerateFiles的单个调用来简化代码,然后使用LINQ对结果进行过滤和排序。下面是一个可能的方法:

string orderNum = "123465";

// Get all files that match the order number
var files = Directory.EnumerateFiles(pathSetting, "*" + orderNum + "*.txt", SearchOption.AllDirectories);

// Filter and order the files by the criteria
var s1 = files.Where(name => name.Contains("red") && !name.StartsWith("H"))
              .OrderByDescending(file => new FileInfo(file).LastWriteTime)
              .FirstOrDefault(); // Get the first file or null if none

var s2 = files.Where(name => name.Contains("red") && name.StartsWith("H"))
              .OrderByDescending(file => new FileInfo(file).LastWriteTime)
              .FirstOrDefault();

var s3 = files.Where(name => name.Contains("blue") && !name.StartsWith("H"))
              .OrderByDescending(file => new FileInfo(file).LastWriteTime)
              .FirstOrDefault();

// Create a list of the files that are not null
var sourceFiles = new List<string>();
if (s1 != null) sourceFiles.Add(s1);
if (s2 != null) sourceFiles.Add(s2);
if (s3 != null) sourceFiles.Add(s3);

// Perform action on the files

字符串
避免条件重复的另一种方法是使用specification pattern

vptzau2j

vptzau2j2#

为了提高效率,您可以通过只对该部分迭代一次来避免磁盘I/O。您也可以使用DirectoryInfo.EnumerateFiles,因为您需要每个候选文件的LastWriteTime。
我怀疑在LINQ中有一些方法可以做到这一点,当你来调整它时不会让你哭,但老式的方法可能会工作得很好:

string searchPattern = "*" + orderNum + "*.txt";

var di = new DirectoryInfo(pathSetting);

var ff = di.EnumerateFiles(searchPattern, SearchOption.AllDirectories);

var noH = "";
var noHDate = DateTime.MinValue;
var withH = "";
var withHDate = DateTime.MinValue;
var blue = "";
var blueDate = DateTime.MinValue;

foreach (var fi in ff)
{
    if (fi.Name.Contains("red", StringComparison.InvariantCultureIgnoreCase))
    {
        if (fi.Name.StartsWith("H"))
        {
            if (fi.LastWriteTime > withHDate)
            {
                withH = fi.FullName;
                withHDate = fi.LastWriteTime;
            }
        }
        else
        {
            if (fi.LastWriteTime > noHDate)
            {
                noH = fi.FullName;
                noHDate = fi.LastWriteTime;
            }
        }
    }

    if (fi.Name.Contains("blue", StringComparison.InvariantCultureIgnoreCase)
        && !fi.Name.StartsWith("H"))    {
        if (fi.LastWriteTime > blueDate)
        {
            blue = fi.FullName;
            blueDate = fi.LastWriteTime;
        }
    };

}

字符串

相关问题