397 lines
12 KiB
C#
397 lines
12 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
|
|
namespace RyzStudio.IO
|
|
{
|
|
public class AccessibleDirectory
|
|
{
|
|
|
|
public static List<string> GetFiles(string path, string pattern, bool searchTopOnly)
|
|
{
|
|
List<string> fileList = new List<string>();
|
|
List<string> directoryList = new List<string>();
|
|
|
|
if (string.IsNullOrWhiteSpace(pattern)) pattern = "*";
|
|
|
|
directoryList.Add(path);
|
|
|
|
while (true)
|
|
{
|
|
if (directoryList.Count <= 0)
|
|
{
|
|
break;
|
|
}
|
|
|
|
string directory = directoryList.First();
|
|
directoryList.RemoveAt(0);
|
|
|
|
if (IsDirectoryAccessible(directory))
|
|
{
|
|
IEnumerable<string> searchDirList = new List<string>();
|
|
|
|
try
|
|
{
|
|
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 (!MatchFileSearchPattern(pattern, Path.GetFileName(item)))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (!IsFileAccessible(item))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
fileList.Add(item);
|
|
}
|
|
}
|
|
}
|
|
|
|
return fileList;
|
|
}
|
|
|
|
public static IEnumerable<string> EnumerateFiles(string path, string pattern, bool searchTopOnly)
|
|
{
|
|
List<string> directoryList = new List<string>();
|
|
|
|
if (string.IsNullOrWhiteSpace(pattern)) pattern = "*";
|
|
|
|
directoryList.Add(path);
|
|
|
|
while (true)
|
|
{
|
|
if (directoryList.Count <= 0)
|
|
{
|
|
yield break;
|
|
}
|
|
|
|
string directory = directoryList.First();
|
|
directoryList.RemoveAt(0);
|
|
|
|
if (IsDirectoryAccessible(directory))
|
|
{
|
|
IEnumerable<string> searchDirList = new List<string>();
|
|
|
|
try
|
|
{
|
|
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 (!MatchFileSearchPattern(pattern, Path.GetFileName(item)))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (!IsFileAccessible(item))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
yield return item;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void GetFiles(string path, string pattern, bool searchTopOnly, Func<string, ulong, int, bool> callback)
|
|
{
|
|
List<string> directoryList = new List<string>();
|
|
ulong searchCount = 0;
|
|
|
|
if (string.IsNullOrWhiteSpace(pattern)) pattern = "*";
|
|
|
|
directoryList.Add(path);
|
|
searchCount++;
|
|
|
|
while (true)
|
|
{
|
|
if (directoryList.Count <= 0)
|
|
{
|
|
break;
|
|
}
|
|
|
|
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);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
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 (!MatchFileSearchPattern(pattern, Path.GetFileName(item)))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (!IsFileAccessible(item))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
callback(item, searchCount, directoryList.Count);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static string GetNextFile(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;
|
|
|
|
bool returnNext = false;
|
|
foreach (string item in Directory.EnumerateFiles(path, "*", SearchOption.TopDirectoryOnly))
|
|
{
|
|
if (!MatchFileSearchPattern(pattern, Path.GetFileName(item)))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (!IsFileAccessible(item))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (returnNext)
|
|
{
|
|
return item;
|
|
}
|
|
|
|
if (Path.GetFileName(item).Equals(filename))
|
|
{
|
|
returnNext = true;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public static bool IsAccessible(string path)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(path)) return false;
|
|
|
|
if (File.Exists(path)) return IsFileAccessible(path);
|
|
if (Directory.Exists(path)) return IsDirectoryAccessible(path);
|
|
|
|
return false;
|
|
}
|
|
|
|
public static bool IsFileAccessible(string filename)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(filename)) return false;
|
|
if (!File.Exists(filename)) return false;
|
|
|
|
try
|
|
{
|
|
FileInfo fi = new FileInfo(filename);
|
|
fi.GetAccessControl();
|
|
}
|
|
catch
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public static bool IsDirectoryAccessible(string path)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(path)) return false;
|
|
if (!Directory.Exists(path)) return false;
|
|
|
|
try
|
|
{
|
|
DirectoryInfo di = new DirectoryInfo(path);
|
|
di.GetAccessControl();
|
|
}
|
|
catch
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public static bool MatchFileSearchPattern(string pattern, string subject)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(pattern))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
Func<string, string, bool> matchPattern = (pattern, subject) =>
|
|
{
|
|
string[] parts = pattern.Split('*');
|
|
if (parts.Length <= 1)
|
|
{
|
|
return subject.Equals(pattern, StringComparison.CurrentCultureIgnoreCase);
|
|
}
|
|
|
|
int pos = 0;
|
|
|
|
for (int i = 0; i < parts.Length; i++)
|
|
{
|
|
if (i <= 0)
|
|
{
|
|
// first
|
|
pos = subject.IndexOf(parts[i], pos, StringComparison.CurrentCultureIgnoreCase);
|
|
if (pos != 0)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
else if (i >= (parts.Length - 1))
|
|
{
|
|
// last
|
|
if (!subject.EndsWith(parts[i], StringComparison.CurrentCultureIgnoreCase))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pos = subject.IndexOf(parts[i], pos, StringComparison.CurrentCultureIgnoreCase);
|
|
if (pos < 0)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
pos += parts[i].Length;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
};
|
|
|
|
Func<string, string, bool> matchAllPattern = (pattern, subject) =>
|
|
{
|
|
int wildcardCount = pattern.Count(x => x.Equals('*'));
|
|
if (wildcardCount <= 0)
|
|
{
|
|
return subject.Equals(pattern, StringComparison.CurrentCultureIgnoreCase);
|
|
}
|
|
else if (wildcardCount == 1)
|
|
{
|
|
string newWildcardPattern = pattern.Replace("*", "");
|
|
|
|
if (pattern.StartsWith("*"))
|
|
{
|
|
return subject.EndsWith(newWildcardPattern, StringComparison.CurrentCultureIgnoreCase);
|
|
}
|
|
else if (pattern.EndsWith("*"))
|
|
{
|
|
return subject.StartsWith(newWildcardPattern, StringComparison.CurrentCultureIgnoreCase);
|
|
}
|
|
else
|
|
{
|
|
return matchPattern(pattern, subject);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return matchPattern(pattern, subject);
|
|
}
|
|
};
|
|
|
|
if (pattern.Contains(';'))
|
|
{
|
|
string[] parts = pattern.Split(';');
|
|
for (int i=0; i<parts.Length; i++)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(parts[i]))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (matchAllPattern(parts[i].Trim(), subject))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
return matchAllPattern(pattern, subject);
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|