using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using Y.FileQueryEngine.UsnOperation;
namespace Y.FileQueryEngine.QueryEngine
{
public class FileQueryEngine
{
///
/// When its values is 1407374883553285(0x5000000000005L), it means this file/folder is under drive root
///
public const UInt64 ROOT_FILE_REFERENCE_NUMBER = 0x5000000000005L;
protected static readonly string excludeFolders = string.Join("|",
new string[]
{
"$RECYCLE.BIN",
"System Volume Information",
"$AttrDef",
"$BadClus",
"$BitMap",
"$Boot",
"$LogFile",
"$Mft",
"$MftMirr",
"$Secure",
"$TxfLog",
"$UpCase",
"$Volume",
"$Extend"
}).ToUpper();
///
/// 获取所有NTFS文件系统的固定磁盘
///
///
public static IEnumerable GetFixedNtfsDrives()
{
return DriveInfo.GetDrives()
.Where(d => d.DriveType == DriveType.Fixed && d.DriveFormat.ToUpper() == "NTFS");
}
///
/// 获取所有NTFS文件系统的磁盘
///
///
public static IEnumerable GetReadyNtfsDrives()
{
return DriveInfo.GetDrives()
.Where(d => d.IsReady && d.DriveFormat.ToUpper() == "NTFS");
}
///
/// 查询磁盘的所有文件
///
///
///
public static List GetAllFiles(DriveInfo drive)
{
var usnOperator = new UsnOperator(drive);
return usnOperator.GetEntries().Where(e => !excludeFolders.Contains(e.FileName.ToUpper())).ToList();
}
public static bool FileIsExist(string drive, long usn)
{
var d = DriveInfo.GetDrives().FirstOrDefault(x => x.Name == drive);
if (d != null)
{
var usnOperator = new UsnOperator(d);
return usnOperator.UsnIsExist(usn);
}
return false;
}
///
/// 查询磁盘的所有文件
///
///
///
public static List GetAllFileEntrys(DriveInfo drive)
{
List result = new List();
var usnOperator = new UsnOperator(drive);
var usnEntries = usnOperator.GetEntries().Where(e => !excludeFolders.Contains(e.FileName.ToUpper()));
var folders = usnEntries.Where(e => e.IsFolder).ToArray();
List paths = GetFolderPath(folders, drive);
var range = usnEntries.Join(
paths,
usn => usn.ParentFileReferenceNumber,
path => path.FileReferenceNumber,
(usn, path) => new FileAndDirectoryEntry(usn, path.Path));
result.AddRange(range);
return result;
}
private static List GetFolderPath(UsnEntry[] folders, DriveInfo drive)
{
Dictionary pathDic = new Dictionary();
pathDic.Add(ROOT_FILE_REFERENCE_NUMBER,
new FrnFilePath(ROOT_FILE_REFERENCE_NUMBER, null, string.Empty, drive.Name.TrimEnd('\\')));
foreach (var folder in folders)
{
pathDic.Add(folder.FileReferenceNumber,
new FrnFilePath(folder.FileReferenceNumber, folder.ParentFileReferenceNumber, folder.FileName));
}
Stack treeWalkStack = new Stack();
foreach (var key in pathDic.Keys)
{
treeWalkStack.Clear();
FrnFilePath currentValue = pathDic[key];
if (string.IsNullOrWhiteSpace(currentValue.Path)
&& currentValue.ParentFileReferenceNumber.HasValue
&& pathDic.ContainsKey(currentValue.ParentFileReferenceNumber.Value))
{
FrnFilePath parentValue = pathDic[currentValue.ParentFileReferenceNumber.Value];
while (string.IsNullOrWhiteSpace(parentValue.Path)
&& parentValue.ParentFileReferenceNumber.HasValue
&& pathDic.ContainsKey(parentValue.ParentFileReferenceNumber.Value))
{
currentValue = parentValue;
if (currentValue.ParentFileReferenceNumber.HasValue
&& pathDic.ContainsKey(currentValue.ParentFileReferenceNumber.Value))
{
treeWalkStack.Push(key);
parentValue = pathDic[currentValue.ParentFileReferenceNumber.Value];
}
else
{
parentValue = null;
break;
}
}
if (parentValue != null)
{
currentValue.Path = BuildPath(currentValue, parentValue);
while (treeWalkStack.Count() > 0)
{
UInt64 walkedKey = treeWalkStack.Pop();
FrnFilePath walkedNode = pathDic[walkedKey];
FrnFilePath parentNode = pathDic[walkedNode.ParentFileReferenceNumber.Value];
walkedNode.Path = BuildPath(walkedNode, parentNode);
}
}
}
}
var result = pathDic.Values.Where(p => !string.IsNullOrWhiteSpace(p.Path) && p.Path.StartsWith(drive.Name)).ToList();
return result;
}
private static string BuildPath(FrnFilePath currentNode, FrnFilePath parentNode)
{
return string.Concat(new string[] { parentNode.Path, "\\", currentNode.FileName });
}
}
}