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>();
}
}
}
|