v2.9.2024.0203 修正net40的客户端调用
智能大石头 authored at 2024-02-03 22:06:24
3.15 KiB
Stardust
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.FileProviders.Physical;
using NewLife;
using NewLife.IO;

namespace Stardust.Extensions.Caches;

class CacheDirectoryContents : IDirectoryContents, IEnumerable<IFileInfo>, IEnumerable
{
    private IEnumerable<IFileInfo>? _entries;

    private readonly String _directory;

    private readonly ExclusionFilters _filters;

    public Boolean Exists => Directory.Exists(_directory);

    /// <summary>索引信息文件。列出扩展显示的文件内容</summary>
    public String? IndexInfoFile { get; set; }

    public CacheDirectoryContents(String directory)
        : this(directory, ExclusionFilters.Sensitive)
    {
    }

    public CacheDirectoryContents(String directory, ExclusionFilters filters)
    {
        _directory = directory ?? throw new ArgumentNullException(nameof(directory));
        _filters = filters;
    }

    public IEnumerator<IFileInfo> GetEnumerator()
    {
        EnsureInitialized();
        return _entries.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        EnsureInitialized();
        return _entries.GetEnumerator();
    }

    [MemberNotNull(nameof(_entries))]
    private void EnsureInitialized()
    {
        try
        {
            _entries = (from info in new DirectoryInfo(_directory).EnumerateFileSystemInfos()
                        where !CacheFileProvider.IsExcluded(info, _filters)
                        select info).Select(info =>
                        {
                            if (info is FileInfo fileInfo)
                                return new PhysicalFileInfo(fileInfo);
                            return info is DirectoryInfo directoryInfo
                                ? (IFileInfo)new PhysicalDirectoryInfo(directoryInfo)
                                : throw new InvalidOperationException("UnexpectedFileSystemInfo");
                        });

            if (!IndexInfoFile.IsNullOrEmpty())
            {
                var fi = _directory.CombinePath(IndexInfoFile).GetBasePath().AsFile();
                if (fi.Exists)
                {
                    var csv = new CsvDb<FileInfoModel>((x, y) => x != null && y != null && x.Name.EqualIgnoreCase(y.Name))
                    {
                        FileName = fi.FullName
                    };
                    var fis = csv.FindAll();
                    if (fis.Count > 0)
                    {
                        var list = _entries.ToList();
                        foreach (var item in fis)
                        {
                            // 把fis里面的项添加到list
                            if (!list.Any(e => e.Name.EqualIgnoreCase(item.Name)))
                                list.Add(item);
                        }

                        _entries = list;
                    }
                }
            }
        }
        catch (Exception ex) when (ex is DirectoryNotFoundException or IOException)
        {
            _entries = Enumerable.Empty<IFileInfo>();
        }
    }
}