/// <summary> /// 导出文件夹及递归其下所有文件、文件夹 /// </summary> private void ExportFolder(FNodeX file, string savePath) { var path = FileHelper.ConnectPath(savePath, file.Directory, file.IsDelete ? "Del_" + file.FileName : file.FileName); //1.1创建文件夹 FileHelper.CreateDirectory(path); var creatime = BaseTypeExtension.ToSafeDateTime(file.Source.CreateTime); if (creatime != null) { Directory.SetCreationTime(path, (DateTime)creatime); } var accessTime = BaseTypeExtension.ToSafeDateTime(file.Source.LastAccessTime); if (accessTime != null) { Directory.SetLastAccessTime(path, (DateTime)accessTime); } var modifyTime = BaseTypeExtension.ToSafeDateTime(file.Source.ModifyTime); if (modifyTime != null) { Directory.SetLastWriteTime(path, (DateTime)modifyTime); } }
public void BuildTree(FNodeX node, Dictionary <ulong, ICollection <FNodeX> > data) { // 构造正常文件树; BuildNormalChildren(node, data); // 装载丢失文件树; }
/// <summary> /// 获取文件系统 /// </summary> /// <param name="device"></param> /// <param name="iAsync"></param> /// <returns></returns> public FNodeX GetFileSystem(IFileSystemDevice device, SingleTaskReporterBase iAsync) { IAsync = iAsync; CreateFileServiceAbstractX(device, iAsync); if (fileServiceX == null) { return(null); } _systemTree = fileServiceX.GetFileSystem(); return(_systemTree); }
/// <summary> /// 获取文件系统 /// </summary> /// <param name="device"></param> /// <param name="iAsync"></param> /// <returns></returns> public FNodeX GetFileSystem(IFileSystemDevice device, IAsyncProgress iAsync) { IAsync = iAsync; CreateFileServiceAbstractX(device, iAsync); if (fileServiceX == null) { return(null); } _systemTree = fileServiceX.GetFileSystem(); return(_systemTree); }
/// <summary> /// 导出单个文件到指定目录 /// isCover是否覆盖已存在的文件,默认不覆盖 /// </summary> private string ExportFile(FNodeX file, string savePath, bool persistRelativePath = true, bool isMedia = false, bool isCover = false) { var path = string.Empty; if (persistRelativePath) { path = FileHelper.ConnectPath(savePath, file.Directory.ToSafeString(), (isMedia && file.IsDelete) ? "Del_" + file.FileName : file.FileName); } else { path = FileHelper.ConnectPath(savePath, (isMedia && file.IsDelete) ? "Del_" + file.FileName : file.FileName); } if (!file.IsFolder) { path = path.TrimEnd('\\'); } if (!isCover && File.Exists(path)) { return(path); } Directory.CreateDirectory(FileHelper.GetFilePath(path)); RecoveryFile(file, path); //Asyn?.Advance(0, string.Format(LanguageManager.Current[Languagekeys.FileServiceLanguage_File_WenJianHuiFuChengGong], file.FullPath.TrimEnd(@"\"))); var creatime = BaseTypeExtension.ToSafeDateTime(file.Source.CreateTime); if (creatime != null) { File.SetCreationTime(path, (DateTime)creatime); } var accessTime = BaseTypeExtension.ToSafeDateTime(file.Source.LastAccessTime); if (accessTime != null) { File.SetLastAccessTime(path, (DateTime)accessTime); } var modifyTime = BaseTypeExtension.ToSafeDateTime(file.Source.ModifyTime); if (modifyTime != null) { File.SetLastWriteTime(path, (DateTime)modifyTime); } return(path); }
/// <summary> /// 分层扫描接口 扫描文件夹 /// </summary> /// <param name="partition">分区</param> /// <returns></returns> public List <FNodeX> GetFileSystemByDir(FNodeX pNode) { LINK_DIR_FILE_NODE_INFO link = new LINK_DIR_FILE_NODE_INFO(); var result = FileServiceCoreDll.ScanFilesByDir(pNode.Mount, GetFileSystemByDirScanCallBack, pNode.Key, ref link); if (0 != result) { } // 加载树结构; var source = BuildDataDictionary(link); BuildTree(pNode, source); return(pNode.Collection); }
/// <summary> /// 导出单个文件到指定目录 /// isCover是否覆盖已存在的文件,默认不覆盖 /// </summary> private void ExportFile(FNodeX file, string savePath, bool isMedia = false, bool isCover = false) { var path = FileHelper.ConnectPath(savePath, file.Directory.ToSafeString(), (isMedia && file.IsDelete) ? "Del_" + file.FileName : file.FileName); if (!file.IsFolder) { path = path.TrimEnd('\\'); } if (!isCover && File.Exists(path)) { return; } const int t = 500 * 1024 * 1024; if (file.Size > t) { return; } Directory.CreateDirectory(FileHelper.GetFilePath(path)); RecoveryFile(file, path); Asyn?.Advance(0, string.Format(LanguageHelperSingle.Instance.GetLanguageByKey(Languagekeys.FileServiceLanguage_File_WenJianHuiFuChengGong), file.FullPath.TrimEnd(@"\"))); var creatime = BaseTypeExtension.ToSafeDateTime(file.Source.CreateTime); if (creatime != null) { File.SetCreationTime(path, (DateTime)creatime); } var accessTime = BaseTypeExtension.ToSafeDateTime(file.Source.LastAccessTime); if (accessTime != null) { File.SetLastAccessTime(path, (DateTime)accessTime); } var modifyTime = BaseTypeExtension.ToSafeDateTime(file.Source.ModifyTime); if (modifyTime != null) { File.SetLastWriteTime(path, (DateTime)modifyTime); } }
/// <summary> /// 恢复文件 /// </summary> /// <param name="file">文件节点对象</param> /// <param name="savePath">保存文件路径</param> /// <param name="isCover">是否覆盖已存在的文件</param> /// <returns></returns> public void ExportFileX(FNodeX file, string savePath, bool isMedia = false, bool isCover = false) { try { if (file.IsFolder) { ExportFolder(file, savePath); } else { ExportFile(file, savePath, isMedia, isCover); } } catch (Exception ex) { LoggerManagerSingle.Instance.Error(string.Format("export file error[{0}]", file.FullPath), ex); } }
private bool RecoveryFile(FNodeX source, string savePath) { var node = source.Source; FILE_RECOVERY_INFO file = new FILE_RECOVERY_INFO(); file.Attr = node.FileAttribute; file.FileId = node.FileId; file.OffSet = node.OffsetBytes; file.OffsetSec = node.OffsetSec; file.ParentFileId = node.ParentFileId; file.Size = node.Size; CHECK_SUM_INFO check = new CHECK_SUM_INFO(); int res = 0; IntPtr fileHandle = IntPtr.Zero; try { fileHandle = FileServiceCoreDll.CreateNewFile(savePath); res = FileServiceCoreDll.RecoveryFile(source.Mount, fileHandle, LpfnRecoveryFileProgressEx, ref file, ref check); if (0 != res) { LoggerManagerSingle.Instance.Error(string.Format("提取文件时底层库FileServiceCoreDll.RecoveryFile失败!错误码:{0}", res)); } } catch (Exception ex) { LoggerManagerSingle.Instance.Error("提取文件时底层库FileServiceCoreDll.RecoveryFile出现异常!", ex); } finally { if (IntPtr.Zero != fileHandle) { FileServiceCoreDll.CloseDevice(fileHandle); } } return(res == 0); }
/// <summary> /// 建立文件树节点 /// </summary> /// <param name="linkInfo"></param> /// <returns></returns> public FNodeX BuildFileXNode(DIR_FILE_NODE_INFO linkInfo) { var file = new FNodeX(); file.FileName = linkInfo.FileName; file.Key = linkInfo.FileId; file.ParentKey = linkInfo.ParentFileId; file.Mount = RunPartition.Mount; file.Source = linkInfo; if (!file.IsDelete) { _normalFolderIdSet.Add(string.Format("{0} - {1}", file.ParentKey, file.Key)); } else { _delFolderIdSet.Add(string.Format("{0} - {1}", file.ParentKey, file.Key)); } return(file); }
/// <summary> /// 创建数据字典 /// </summary> /// <param name="linkInfo"></param> /// <returns></returns> public Dictionary <ulong, ICollection <FNodeX> > BuildDataDictionary(LINK_DIR_FILE_NODE_INFO linkInfo) { var data = new Dictionary <ulong, ICollection <FNodeX> >(); while (linkInfo.next != IntPtr.Zero) { linkInfo = linkInfo.next.ToStruct <LINK_DIR_FILE_NODE_INFO>(); if (linkInfo.NodeDataInfo.FileId == linkInfo.NodeDataInfo.ParentFileId) { continue; } ulong parentId = linkInfo.NodeDataInfo.ParentFileId; FNodeX file = BuildFileXNode(linkInfo.NodeDataInfo); if (data.ContainsKey(parentId)) { if (!file.IsDelete) { data[parentId].Add(file); } } else { data.Add(parentId, new Collection <FNodeX> { file }); } if (RunPartition.VolName != null && RunPartition.VolName.Equals("userdata", StringComparison.OrdinalIgnoreCase)) { GetUserPartitionFiles.Add(file); } AllFileNodeX.Add(file); } foreach (var nfid in _delFolderIdSet) { if (_normalFolderIdSet.Contains(nfid)) { _problemFolderIdSet.Add(nfid); } } return(data); }
/// <summary> /// 获取文件系统 /// </summary> /// <returns></returns> public FNodeX GetFileSystem() { _isStop = false; if (Device == null) { return(null); } // 打开设备 OpenDevice(); // 加载设备分区 if (Device.Parts.Count == 0) { LoadDevicePartitions(); } var fileTree = new FNodeX { IsRoot = true }; int count = Device.Parts.Count; // 构建分区文件系统 foreach (var part in Device.Parts) { RunPartition = (FileSystemPartition)part; Asyn?.Advance(1 / count, string.Format(LanguageHelperSingle.Instance.GetLanguageByKey(Languagekeys.FileServiceLanguage_File_ZuZhuangFenQuDeWenJianXiTongSh), RunPartition.Name)); MountDevice(); var tree = ScanFileSystem(Device, RunPartition); if (tree == null) { continue; } // 扫描设备 fileTree.Collection.Add(tree); if (_isStop) { break; } } LoggerManagerSingle.Instance.Info(string.Format("扫描文件系统结束, 得到文件/文件夹数:{0}", AllFileNodeX.Count)); Asyn?.Advance(1, LanguageHelperSingle.Instance.GetLanguageByKey(Languagekeys.FileServiceLanguage_File_WenJianXiTongZuZhuangWanBi)); return(fileTree); }
private byte[] ReadFileBytes(FNodeX source, int offset = 0, int len = 0) { var node = source.Source; FILE_RECOVERY_INFO file = new FILE_RECOVERY_INFO(); file.Attr = node.FileAttribute; file.FileId = node.FileId; file.OffSet = node.OffsetBytes; file.OffsetSec = node.OffsetSec; file.ParentFileId = node.ParentFileId; file.Size = node.Size; byte[] buff = new byte[len]; try { FileServiceCoreDll.ReadFileByBottom(source.Mount, ref file, (ulong)offset, len, buff); } catch (Exception ex) { LoggerManagerSingle.Instance.Error("提取文件时底层库FileServiceCoreDll.ReadFileByBottom出现异常!", ex); } return(buff); }
private FNodeX ScanFileSystem(IFileSystemDevice device, FileSystemPartition partition) { ScanCallBack callBack = (ref ScanCallBackData pdi) => { }; LINK_DIR_FILE_NODE_INFO link = new LINK_DIR_FILE_NODE_INFO(); LIST_FILE_RAW_TYPE_INFO raw = CreatRawLink(); try { var result = FileServiceCoreDll.ScanFiles(partition.Mount, callBack, ref link, device.ScanModel, ref raw, 0); if (result != 0) { LoggerManagerSingle.Instance.Error(string.Format("获取文件系统(名称:{ 0},描述: { 1},大小: { 2})失败,错误码: { 3}", partition.Name, partition.Discription, partition.Size, result)); return(null); } partition.NodeLinkList = link; } catch (Exception ex) { LoggerManagerSingle.Instance.Error(string.Format("获取文件系统(名称:{0},描述:{1},大小:{2},Mount:{3})时底层dll出错", partition.Name, partition.Discription, partition.Size, partition.Mount), ex); return(null); } // 构建当前分区节点 var treeNode = new FNodeX { Source = link.NodeDataInfo, FileName = partition.VolName, IsRoot = true, IsPartition = true, Key = link.NodeDataInfo.FileId, ParentKey = link.NodeDataInfo.ParentFileId }; // 加载树结构; var source = BuildDataDictionary(link); BuildTree(treeNode, source); return(treeNode); }
public void BuildNormalChildren(FNodeX node, Dictionary <ulong, ICollection <FNodeX> > dictionary) { if (dictionary.ContainsKey(node.Key)) { if (_problemFolderIdSet.Contains(string.Format("{0} - {1}", node.ParentKey, node.Key)) && node.IsDelete) { return; } var files = dictionary[node.Key]; dictionary.Remove(node.Key); foreach (var fileX in files) { fileX.Directory = node.FullPath; node.Collection.Add(fileX); if (fileX.IsFolder) { BuildNormalChildren(fileX, dictionary); } } } }
/// <summary> /// 分层扫描接口 扫描分区 /// </summary> /// <param name="partition">分区</param> /// <returns></returns> public List <FNodeX> GetFileSystemByDir(FileSystemPartition partition) { RunPartition = partition; MountDevice(); VOL_BPB_INFO vol = new VOL_BPB_INFO(); var result = FileServiceCoreDll.GetPartInfo(partition.Mount, ref vol); if (0 != result) { } LINK_DIR_FILE_NODE_INFO link = new LINK_DIR_FILE_NODE_INFO(); result = FileServiceCoreDll.ScanFilesByDir(partition.Mount, GetFileSystemByDirScanCallBack, vol.root_ino, ref link); if (0 != result) { } // 构建当前分区节点 var treeNode = new FNodeX { Source = link.NodeDataInfo, FileName = partition.VolName, IsRoot = true, IsPartition = true, Key = link.NodeDataInfo.FileId, ParentKey = link.NodeDataInfo.ParentFileId }; // 加载树结构; var source = BuildDataDictionary(link); BuildTree(treeNode, source); return(treeNode.Collection); }
/// <summary> /// 恢复文件 /// </summary> /// <param name="file">文件节点对象</param> /// <param name="persistRelativePath">是否保留相对路径</param> /// <param name="savePath">保存文件路径</param> /// <param name="isCover">是否覆盖已存在的文件</param> /// <returns>如果是文件 则返回本地保存路径 如果是文件夹 暂时返回null</returns> public string ExportFileX(FNodeX file, string savePath, bool persistRelativePath = true, bool isMedia = false, bool isCover = false, bool isThrowEx = false) { try { if (file.IsFolder) { ExportFolder(file, savePath, persistRelativePath); } else { return(ExportFile(file, savePath, persistRelativePath, isMedia, isCover)); } } catch (Exception ex) { LoggerManagerSingle.Instance.Error(string.Format("export file error[{0}]", file.FullPath), ex); if (isThrowEx) { throw; } } return(null); }
/// <summary> /// 文件导出 /// </summary> /// <param name="file"></param> /// <param name="path"></param> /// <param name="isCover"></param> /// <returns></returns> public void ExportFile(FNodeX file, string path, bool isCover = false) { fileServiceX.ExportFileX(file, path, isCover); }