本文只针对NTFS格式化的磁盘文件快速检索,速度不是非常快,是让你震惊。

一般用文件遍历的方法检索一个50G的文件夹需要几十分钟甚至一个小时的时间,而用本方法只需几秒。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using Microsoft.VisualBasic;public class MFTScanner
{private static IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);private const uint GENERIC_READ = 0x80000000;private const int FILE_SHARE_READ = 0x1;private const int FILE_SHARE_WRITE = 0x2;private const int OPEN_EXISTING = 3;private const int FILE_READ_ATTRIBUTES = 0x80;private const int FILE_NAME_IINFORMATION = 9;private const int FILE_FLAG_BACKUP_SEMANTICS = 0x2000000;private const int FILE_OPEN_FOR_BACKUP_INTENT = 0x4000;private const int FILE_OPEN_BY_FILE_ID = 0x2000;private const int FILE_OPEN = 0x1;private const int OBJ_CASE_INSENSITIVE = 0x40;private const int FSCTL_ENUM_USN_DATA = 0x900b3;[StructLayout(LayoutKind.Sequential)]private struct MFT_ENUM_DATA{public long StartFileReferenceNumber;public long LowUsn;public long HighUsn;}[StructLayout(LayoutKind.Sequential)]private struct USN_RECORD{public int RecordLength;public short MajorVersion;public short MinorVersion;public long FileReferenceNumber;public long ParentFileReferenceNumber;public long Usn;public long TimeStamp;public int Reason;public int SourceInfo;public int SecurityId;public FileAttribute FileAttributes;public short FileNameLength;public short FileNameOffset;}[StructLayout(LayoutKind.Sequential)]private struct IO_STATUS_BLOCK{public int Status;public int Information;}[StructLayout(LayoutKind.Sequential)]private struct UNICODE_STRING{public short Length;public short MaximumLength;public IntPtr Buffer;}[StructLayout(LayoutKind.Sequential)]private struct OBJECT_ATTRIBUTES{public int Length;public IntPtr RootDirectory;public IntPtr ObjectName;public int Attributes;public int SecurityDescriptor;public int SecurityQualityOfService;}MFT_ENUM_DATA[DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)]private static extern bool DeviceIoControl(IntPtr hDevice, int dwIoControlCode, ref MFT_ENUM_DATA lpInBuffer, int nInBufferSize, IntPtr lpOutBuffer, int nOutBufferSize, ref int lpBytesReturned, IntPtr lpOverlapped);[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]private static extern IntPtr CreateFile(string lpFileName, uint dwDesiredAccess, int dwShareMode, IntPtr lpSecurityAttributes, int dwCreationDisposition, int dwFlagsAndAttributes, IntPtr hTemplateFile);[DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)]private static extern Int32 CloseHandle(IntPtr lpObject);[DllImport("ntdll.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)]private static extern int NtCreateFile(ref IntPtr FileHandle, int DesiredAccess, ref OBJECT_ATTRIBUTES ObjectAttributes, ref IO_STATUS_BLOCK IoStatusBlock, int AllocationSize, int FileAttribs, int SharedAccess, int CreationDisposition, int CreateOptions, int EaBuffer,int EaLength);[DllImport("ntdll.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)]private static extern int NtQueryInformationFile(IntPtr FileHandle, ref IO_STATUS_BLOCK IoStatusBlock, IntPtr FileInformation, int Length, int FileInformationClass);private IntPtr m_hCJ;private IntPtr m_Buffer;private int m_BufferSize;private string m_DriveLetter;private class FSNode{public long FRN;public long ParentFRN;public string FileName;public bool IsFile;public FSNode(long lFRN, long lParentFSN, string sFileName, bool bIsFile){FRN = lFRN;ParentFRN = lParentFSN;FileName = sFileName;IsFile = bIsFile;}}private IntPtr OpenVolume(string szDriveLetter){IntPtr hCJ = default(IntPtr);volume handlem_DriveLetter = szDriveLetter;hCJ = CreateFile("\\\\.\\" + szDriveLetter, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);return hCJ;}private void Cleanup(){if (m_hCJ != IntPtr.Zero){// Close the volume handle.CloseHandle(m_hCJ);m_hCJ = INVALID_HANDLE_VALUE;}if (m_Buffer != IntPtr.Zero){// Free the allocated memoryMarshal.FreeHGlobal(m_Buffer);m_Buffer = IntPtr.Zero;}}public IEnumerable<String> EnumerateFiles(string szDriveLetter){try{var usnRecord = default(USN_RECORD);var mft = default(MFT_ENUM_DATA);var dwRetBytes = 0;var cb = 0;var dicFRNLookup = new Dictionary<long, FSNode>();var bIsFile = false;// This shouldn't be called more than once.if (m_Buffer.ToInt32() != 0){throw new Exception("invalid buffer");}// Assign buffer sizem_BufferSize = 65536;//64KB// Allocate a buffer to use for reading records.m_Buffer = Marshal.AllocHGlobal(m_BufferSize);// correct pathszDriveLetter = szDriveLetter.TrimEnd('\\');// Open the volume handle m_hCJ = OpenVolume(szDriveLetter);// Check if the volume handle is valid.if (m_hCJ == INVALID_HANDLE_VALUE){throw new Exception("Couldn't open handle to the volume.");}mft.StartFileReferenceNumber = 0;mft.LowUsn = 0;mft.HighUsn = long.MaxValue;do{if (DeviceIoControl(m_hCJ, FSCTL_ENUM_USN_DATA, ref mft, Marshal.SizeOf(mft), m_Buffer, m_BufferSize, ref dwRetBytes, IntPtr.Zero)){cb = dwRetBytes;// Pointer to the first recordIntPtr pUsnRecord = new IntPtr(m_Buffer.ToInt32() + 8);while ((dwRetBytes > 8)){// Copy pointer to USN_RECORD structure.usnRecord = (USN_RECORD)Marshal.PtrToStructure(pUsnRecord, usnRecord.GetType());// The filename within the USN_RECORD.string FileName = Marshal.PtrToStringUni(new IntPtr(pUsnRecord.ToInt32() + usnRecord.FileNameOffset), usnRecord.FileNameLength / 2);bIsFile = !usnRecord.FileAttributes.HasFlag(FileAttribute.Directory);dicFRNLookup.Add(usnRecord.FileReferenceNumber, new FSNode(usnRecord.FileReferenceNumber, usnRecord.ParentFileReferenceNumber, FileName, bIsFile));// Pointer to the next record in the buffer.pUsnRecord = new IntPtr(pUsnRecord.ToInt32() + usnRecord.RecordLength);dwRetBytes -= usnRecord.RecordLength;}// The first 8 bytes is always the start of the next USN.mft.StartFileReferenceNumber = Marshal.ReadInt64(m_Buffer, 0);}else{break; // TODO: might not be correct. Was : Exit Do}} while (!(cb <= 8));// Resolve all paths for Filesforeach (FSNode oFSNode in dicFRNLookup.Values.Where(o => o.IsFile)){string sFullPath = oFSNode.FileName;FSNode oParentFSNode = oFSNode;while (dicFRNLookup.TryGetValue(oParentFSNode.ParentFRN, out oParentFSNode)){sFullPath = string.Concat(oParentFSNode.FileName, "\\", sFullPath);}sFullPath = string.Concat(szDriveLetter, "\\", sFullPath);yield return sFullPath;}}finally{cleanupCleanup();}}
}

调用方法:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Diagnostics;namespace ConsoleApplication28
{class Program{static void Main(string[] args){var sw = Stopwatch.StartNew();var files = EnumerateFiles("f:").ToArray();var elapsed = sw.ElapsedMilliseconds.ToString();Console.WriteLine(string.Format("Found {0} files, elapsed {1} ms", files.Length, elapsed));}}
}

方法只能传磁盘名

C#快速找出磁盘内的所有文件相关推荐

  1. 如何找出电脑内的重复文件,查找电脑磁盘重复文件的方法

    不少小伙伴都有收集各种软件.图片和资料的习惯,但是时间久了,有许多软件.图片和资料已经下载过了,但是忘记了,又重新下载了,这样导致电脑里面有很多重复的软件.图片和资料.如何找出电脑内的重复文件? 我们 ...

  2. javascript 几句话快速找出字符串内指定字符的下标。

    今天在和朋友讨论如何快速找出字符串内指定字符的下标 于是就出现了下面的写法: 写法1 var str ="this is javascript" var resault ={ind ...

  3. 计算机一级查找同类型文件,如何快捷找出电脑内的重复文件

    有时特喜欢收集各种软件和资料,但是时间久了,很多软件和资料之前下载过了,后来不记得了,又下载了,这样重复的非常多.这样重复的文件多了,占了大量的磁盘空间,也影响电脑运行性能,当然是要清理掉,但这些文件 ...

  4. 如何测试电脑软件重复或多,如何快捷找出电脑内的重复文件(两个工具)

    我特喜欢收集各种软件和资料,但是时间久了,很多软件和资料之前下载过了,后来不记得了,又下载了,这样重复的非常多.还有,我喜欢备份文件,就算一些普通的文件,也会随手临时备份一下,过后,没有删除,就忘记了 ...

  5. c语言中查重,体验CCleaner查重功能,快速找出电脑中的重复文件

    在我们的电脑中,除了会有很多工作上的文件,还会有大量的生活照片.生活视频.当自己去整理这些文件的时候,会发现有很多都是重复的,太占用电脑磁盘空间了.可是要自己一个个去查找一个个去删除,那真是太浪费精力 ...

  6. 计算机中文件可以重名吗,如何快捷找出电脑内的重复文件(两个工具)

    我特喜欢收集各种软件和资料,但是时间久了,很多软件和资料之前下载过了,后来不记得了,又下载了,这样重复的非常多.还有,我喜欢备份文件,就算一些普通的文件,也会随手临时备份一下,过后,没有删除,就忘记了 ...

  7. 拼多多搜索怎么测图测款?教你快速找出店铺内潜在爆款

    测图测款的重要性,不用多说大家也都知道.但实际上,很多人在这个环节都没做好. 那么要怎么测款才能选出具有爆款潜质的好产品呢? 资深的运营首选就是通过直通车数据来测图测款,怎么操作?下面一起来看看: 1 ...

  8. 快速找出QQ群成员中不在名单内的人

    快速找出QQ群成员中不在名单内的人 Created: Aug 15, 2020 10:21 PM Tags: Python, 计划中 Updated: Aug 17, 2020 10:45 PM 需求 ...

  9. 第1章 游戏之乐——快速找出故障机器

    转载:编程之美_1.5_快速找出机器故障 题目:假设一个机器只存储一个标号为ID的记录,假设每份数据保存2个备份,这样就有2个机器存储了相同的数据.其中ID是小于10亿的整数 问题1.在某个时间,如果 ...

最新文章

  1. stm32无法进入串口接收中断
  2. 阿里云开源 image-syncer 工具,容器镜像迁移同步的终极利器
  3. 【产品]如何建立交互设计自查表
  4. [转]IE11下Forms身份认证无法保存Cookie的问题
  5. Objective-C学习笔记(一)–类
  6. 拳王虚拟项目公社:流量如何截流?各类流量截流技巧分享
  7. (14)Spring框架----Spring 注解机制和XML配置机制之间的比较
  8. 51单片机十字交通灯程序设计
  9. 开启智慧新生活 新余市智慧城市建设全省率先
  10. python和excel的优缺点_Excel不好吗?为什么非要学python?
  11. android 横屏转竖屏,(转)Android强制设置横屏或竖屏
  12. 严蔚敏《数据结构》 迪杰斯特拉算法
  13. 台式计算机图形设置,如何打开计算机图形设置以提高游戏质量?
  14. 网点分布图怎么做,用地图制作客户分布图
  15. Java实现word文档转换为pdf,jodconverter
  16. 【操作系统概念-作业1】Introduction
  17. 科技筑梦创新成长 “探知未来”一直在路上
  18. 麒麟操作系统之重置密码
  19. 人机交互:虚拟翻书与空中翻书的种类与技术原理及案例展示
  20. Java设计模式——观察者模式

热门文章

  1. linux 文本 编辑 软件下载,文本编辑软件 Atom 1.5.0 已经发布下载
  2. SpringBoot项目打成War包??
  3. 学用软件:laTex软件初体验
  4. Scala案例:词频统计
  5. 【codevs1285】【BZOJ1208】宠物收养所,splay练习
  6. 单击跳转_如何在100张工作表中快速实现查找和跳转
  7. pandas dataframe column_数据处理的瑞士军刀pandas | 火星技术帖
  8. 开源网店系统_做仿货国外网店系统被谷歌禁掉该怎么办?
  9. c++指定在某一线程运行_深入理解Java虚拟机-运行时数据区
  10. 【英语学习】【Level 08】U01 Let's Read L1 All the world's a stage