Changed accessible-directory to cancellable TPL

This commit is contained in:
Ray 2021-12-05 19:35:45 +00:00
parent 5b9a6d4633
commit 68c929b7cb

View File

@ -3,75 +3,101 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace RyzStudio.IO namespace RyzStudio.IO
{ {
public class AccessibleDirectory public class AccessibleDirectory
{ {
public static List<string> GetFiles(string path, string pattern, bool searchTopOnly) public static List<string> GetFiles(string path, string pattern, bool searchTopOnly) => GetFilesAsync(path, pattern, searchTopOnly).Result;
public static Task<List<string>> GetFilesAsync(string path, string pattern, bool searchTopOnly)
{ {
List<string> fileList = new List<string>(); CancellationToken cancellationToken = new CancellationToken();
List<string> directoryList = new List<string>();
if (string.IsNullOrWhiteSpace(pattern)) pattern = "*"; return GetFilesAsync(path, pattern, searchTopOnly, cancellationToken);
}
directoryList.Add(path); public static Task<List<string>> GetFilesAsync(string path, string pattern, bool searchTopOnly, CancellationToken cancellationToken)
{
while (true) return Task.Run<List<string>>(() =>
{ {
if (directoryList.Count <= 0) List<string> fileList = new List<string>();
List<string> directoryList = new List<string>();
if (string.IsNullOrWhiteSpace(pattern)) pattern = "*";
if (cancellationToken.IsCancellationRequested) return fileList;
directoryList.Add(path);
while (true)
{ {
break; if (directoryList.Count <= 0)
}
string directory = directoryList.First();
directoryList.RemoveAt(0);
if (IsDirectoryAccessible(directory))
{
IEnumerable<string> searchDirList = new List<string>();
try
{ {
searchDirList = Directory.EnumerateDirectories(directory, "*", SearchOption.TopDirectoryOnly); break;
}
catch (Exception)
{
continue;
} }
if (!searchTopOnly) if (cancellationToken.IsCancellationRequested) return fileList;
string directory = directoryList.First();
directoryList.RemoveAt(0);
if (IsDirectoryAccessible(directory))
{ {
foreach (string item in searchDirList) IEnumerable<string> searchDirList = new List<string>();
if (cancellationToken.IsCancellationRequested) return fileList;
try
{ {
if (!IsDirectoryAccessible(item)) searchDirList = Directory.EnumerateDirectories(directory, "*", SearchOption.TopDirectoryOnly);
}
catch (Exception)
{
continue;
}
if (!searchTopOnly)
{
foreach (string item in searchDirList)
{
if (!IsDirectoryAccessible(item))
{
continue;
}
directoryList.Add(item);
}
}
foreach (string item in Directory.EnumerateFiles(directory, "*", SearchOption.TopDirectoryOnly))
{
if (cancellationToken.IsCancellationRequested) return fileList;
if (!MatchFileSearchPattern(pattern, Path.GetFileName(item)))
{ {
continue; continue;
} }
directoryList.Add(item); if (!IsFileAccessible(item))
} {
} continue;
}
foreach (string item in Directory.EnumerateFiles(directory, "*", SearchOption.TopDirectoryOnly)) fileList.Add(item);
{
if (!MatchFileSearchPattern(pattern, Path.GetFileName(item))) if (cancellationToken.IsCancellationRequested) return fileList;
{
continue;
} }
if (!IsFileAccessible(item)) if (cancellationToken.IsCancellationRequested) return fileList;
{
continue;
}
fileList.Add(item);
} }
} }
}
return fileList; return fileList;
});
} }
public static IEnumerable<string> EnumerateFiles(string path, string pattern, bool searchTopOnly) public static IEnumerable<string> EnumerateFiles(string path, string pattern, bool searchTopOnly)
@ -136,145 +162,179 @@ namespace RyzStudio.IO
} }
} }
public static void GetFiles(string path, string pattern, bool searchTopOnly, Func<string, ulong, int, bool> callback) public static void GetFiles(string path, string pattern, bool searchTopOnly, Func<string, ulong, int, bool> callback) => GetFilesAsync(path, pattern, searchTopOnly, callback);
public static Task GetFilesAsync(string path, string pattern, bool searchTopOnly, Func<string, ulong, int, bool> callback)
{ {
List<string> directoryList = new List<string>(); CancellationToken cancellationToken = new CancellationToken();
ulong searchCount = 0;
if (string.IsNullOrWhiteSpace(pattern)) pattern = "*"; return GetFilesAsync(path, pattern, searchTopOnly, callback, cancellationToken);
}
directoryList.Add(path); public static Task GetFilesAsync(string path, string pattern, bool searchTopOnly, Func<string, ulong, int, bool> callback, CancellationToken cancellationToken)
searchCount++; {
return Task.Run(() =>
while (true)
{ {
if (directoryList.Count <= 0) List<string> directoryList = new List<string>();
ulong searchCount = 0;
if (string.IsNullOrWhiteSpace(pattern)) pattern = "*";
if (cancellationToken.IsCancellationRequested) return;
directoryList.Add(path);
searchCount++;
while (true)
{ {
break; if (directoryList.Count <= 0)
}
string directory = directoryList.First();
directoryList.RemoveAt(0);
callback(null, searchCount, directoryList.Count);
if (IsDirectoryAccessible(directory))
{
IEnumerable<string> searchDirList = new List<string>();
try
{ {
searchDirList = Directory.EnumerateDirectories(directory, "*", SearchOption.TopDirectoryOnly); break;
}
catch (Exception)
{
continue;
} }
if (!searchTopOnly) if (cancellationToken.IsCancellationRequested) return;
string directory = directoryList.First();
directoryList.RemoveAt(0);
callback(null, searchCount, directoryList.Count);
if (IsDirectoryAccessible(directory))
{ {
foreach (string item in searchDirList) IEnumerable<string> searchDirList = new List<string>();
try
{ {
if (!IsDirectoryAccessible(item)) searchDirList = Directory.EnumerateDirectories(directory, "*", SearchOption.TopDirectoryOnly);
}
catch (Exception)
{
continue;
}
if (cancellationToken.IsCancellationRequested) return;
if (!searchTopOnly)
{
foreach (string item in searchDirList)
{
if (!IsDirectoryAccessible(item))
{
continue;
}
directoryList.Add(item);
searchCount++;
callback(null, searchCount, directoryList.Count);
}
}
foreach (string item in Directory.EnumerateFiles(directory, "*", SearchOption.TopDirectoryOnly))
{
if (cancellationToken.IsCancellationRequested) return;
if (!MatchFileSearchPattern(pattern, Path.GetFileName(item)))
{ {
continue; continue;
} }
directoryList.Add(item); if (!IsFileAccessible(item))
searchCount++; {
continue;
}
callback(null, searchCount, directoryList.Count); callback(item, searchCount, directoryList.Count);
if (cancellationToken.IsCancellationRequested) return;
} }
}
foreach (string item in Directory.EnumerateFiles(directory, "*", SearchOption.TopDirectoryOnly)) if (cancellationToken.IsCancellationRequested) return;
}
}
});
}
public static string GetNextFile(string filepath, string pattern) => GetNextFileAsync(filepath, pattern).Result;
public static Task<string> GetNextFileAsync(string filepath, string pattern)
{
return Task.Run(() =>
{
if (string.IsNullOrWhiteSpace(filepath)) return null;
string path = Path.GetDirectoryName(filepath);
if (string.IsNullOrWhiteSpace(path)) return null;
string filename = Path.GetFileName(filepath);
if (string.IsNullOrWhiteSpace(filename)) return null;
bool returnNext = false;
foreach (string item in Directory.EnumerateFiles(path, "*", SearchOption.TopDirectoryOnly))
{
if (!MatchFileSearchPattern(pattern, Path.GetFileName(item)))
{ {
if (!MatchFileSearchPattern(pattern, Path.GetFileName(item))) continue;
{ }
continue;
}
if (!IsFileAccessible(item)) if (!IsFileAccessible(item))
{ {
continue; continue;
} }
callback(item, searchCount, directoryList.Count); if (returnNext)
{
return item;
}
if (Path.GetFileName(item).Equals(filename))
{
returnNext = true;
} }
} }
}
return null;
});
} }
public static string GetNextFile(string filepath, string pattern) public static string GetPreviousFile(string filepath, string pattern) => GetPreviousFileAsync(filepath, pattern).Result;
public static Task<string> GetPreviousFileAsync(string filepath, string pattern)
{ {
if (string.IsNullOrWhiteSpace(filepath)) return null; return Task.Run(() =>
string path = Path.GetDirectoryName(filepath);
if (string.IsNullOrWhiteSpace(path)) return null;
string filename = Path.GetFileName(filepath);
if (string.IsNullOrWhiteSpace(filename)) return null;
bool returnNext = false;
foreach (string item in Directory.EnumerateFiles(path, "*", SearchOption.TopDirectoryOnly))
{ {
if (!MatchFileSearchPattern(pattern, Path.GetFileName(item))) if (string.IsNullOrWhiteSpace(filepath)) return null;
string path = Path.GetDirectoryName(filepath);
if (string.IsNullOrWhiteSpace(path)) return null;
string filename = Path.GetFileName(filepath);
if (string.IsNullOrWhiteSpace(filename)) return null;
StringBuilder sb = new StringBuilder();
foreach (string item in Directory.EnumerateFiles(path, "*", SearchOption.TopDirectoryOnly))
{ {
continue; if (!MatchFileSearchPattern(pattern, Path.GetFileName(item)))
{
continue;
}
if (!IsFileAccessible(item))
{
continue;
}
sb.Clear();
sb.Append(item);
if (Path.GetFileName(item).Equals(filename))
{
return (sb.Length <= 0) ? null : sb.ToString();
}
} }
if (!IsFileAccessible(item)) return null;
{ });
continue;
}
if (returnNext)
{
return item;
}
if (Path.GetFileName(item).Equals(filename))
{
returnNext = true;
}
}
return null;
}
public static string GetPreviousFile(string filepath, string pattern)
{
if (string.IsNullOrWhiteSpace(filepath)) return null;
string path = Path.GetDirectoryName(filepath);
if (string.IsNullOrWhiteSpace(path)) return null;
string filename = Path.GetFileName(filepath);
if (string.IsNullOrWhiteSpace(filename)) return null;
StringBuilder sb = new StringBuilder();
foreach (string item in Directory.EnumerateFiles(path, "*", SearchOption.TopDirectoryOnly))
{
if (!MatchFileSearchPattern(pattern, Path.GetFileName(item)))
{
continue;
}
if (!IsFileAccessible(item))
{
continue;
}
sb.Clear();
sb.Append(item);
if (Path.GetFileName(item).Equals(filename))
{
return (sb.Length <= 0) ? null : sb.ToString();
}
}
return null;
} }
public static bool IsAccessible(string path) public static bool IsAccessible(string path)