iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >C#如何实现快速查询文件
  • 758
分享到

C#如何实现快速查询文件

2023-07-02 11:07:46 758人浏览 薄情痞子
摘要

今天小编给大家分享一下C#如何实现快速查询文件的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。相信使用过Everything的

今天小编给大家分享一下C#如何实现快速查询文件的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

相信使用过Everything的人都对其超快的搜索速度印象非常深刻,它的主要原理是通过扫描NTFS磁盘的USN Journal读取的文件列表,而不是磁盘目录,由于USN Journal非常小,因此能实现快速搜索。

由于.net程序的Dll基本上是通用的,在C#中也可以直接使用它。

    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 FileAttributes 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 handle            m_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 memory                Marshal.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 size                m_BufferSize = 65536;                //64KB                // Allocate a buffer to use for reading records.                m_Buffer = Marshal.AllocHGlobal(m_BufferSize);                // correct path                szDriveLetter = szDriveLetter.TrimEnd('\\');                // Open the volume handle                m_hCJ = OpenVolume(szDriveLetter);                // Check if the volume handle is valid.                if (m_hCJ == INVALID_HANDLE_VALUE)                {                    string errorMsg = "Couldn't open handle to the volume.";                    if (!IsAdministrator())                        errorMsg += "Current user is not administrator";                    throw new Exception(errorMsg);                }                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 record                        IntPtr 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(FileAttributes.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 Files                foreach (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            {                //// cleanup                Cleanup();            }        }        public static bool IsAdministrator()        {            windowsIdentity identity = WindowsIdentity.GetCurrent();            WindowsPrincipal principal = new WindowsPrincipal(identity);            return principal.IsInRole(WindowsBuiltInRole.Administrator);        }    }

本文还提供了一个扩展方法,方便我们获取某个磁盘下的所有的文件名。 

    public static class DriveInfoExtension    {        public static IEnumerable<String> EnumerateFiles(this DriveInfo drive)        {            return (new MFTScanner()).EnumerateFiles(drive.Name);        }    }

需要注意的是,读取USN Journal是需要管理员权限的,因此使用这个类需要管理员权限才能正常运行。

另外,这个类封装的也略为简单,只读取了文件名,实际上还可以读取文件大小,属性等常用信息,修改一下代码非常容易获取这些属性。通过它们可以非常方便写出一些分析磁盘空间占用的程序,这里就不举例了。

以上就是“C#如何实现快速查询文件”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注编程网精选频道。

--结束END--

本文标题: C#如何实现快速查询文件

本文链接: https://www.lsjlt.com/news/341485.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C#如何实现快速查询文件
    今天小编给大家分享一下C#如何实现快速查询文件的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。相信使用过Everything的...
    99+
    2023-07-02
  • C#实现快速查询文件的方法
    相信使用过Everything的人都对其超快的搜索速度印象非常深刻,它的主要原理是通过扫描NTFS磁盘的USN Journal读取的文件列表,而不是磁盘目录,由于USN Journa...
    99+
    2024-04-02
  • win10如何快速查找文件
    在Windows 10中,你可以使用以下几种方法来快速查找文件:1. 使用文件资源管理器:打开文件资源管理器并选择要搜索的驱动器或文...
    99+
    2023-09-18
    win10
  • Kylin如何实现快速查询和聚合计算
    Kylin是一个开源的分布式分析引擎,可以通过预先计算和预聚合数据来实现快速查询和聚合计算。其主要特点包括: Cube预计算:K...
    99+
    2024-04-02
  • Linux中如何快速查找文件
    小编给大家分享一下Linux中如何快速查找文件,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!1. findfind 命令应该是最经典的命令了,谈到搜索工具第一个想...
    99+
    2023-06-27
  • 快速查找文件
    查看文件用的软件有:1、ES文件浏览器;2、WPS Office;3、文件解压王;4、CAD迷你看图;5、石墨文档。ES文件浏览器是一款功能强大的免费文件浏览管理器,可以在这款软件中完成文档的管理、浏览和云空间存储。一、ES文件浏览器这是一...
    99+
    2023-07-10
  • PHP Spring 文件同步:如何快速实现?
    在现代企业中,文件同步是非常重要的。特别是当企业有多个部门时,文件的共享和同步将是一个必不可少的任务。在这种情况下,使用 PHP Spring 是一种快速实现文件同步的方法。 PHP Spring 是一个 PHP 框架,它提供了一个简单而...
    99+
    2023-08-06
    spring 文件 同步
  • Mybatis怎么快速实现分页查询
    这篇文章主要讲解了“Mybatis怎么快速实现分页查询”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Mybatis怎么快速实现分页查询”吧!目录前言首先创建一个Maven项目数据库中创建一张...
    99+
    2023-06-20
  • Ubuntu如何快速查找某个文件
    这篇文章主要为大家展示了“Ubuntu如何快速查找某个文件”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Ubuntu如何快速查找某个文件”这篇文章吧。Ubuntu简介Ubuntu是一个以桌面应用...
    99+
    2023-06-27
  • Mybatis利用分页插件PageHelper快速实现分页查询
    目录前言 首先创建一个Maven项目 数据库中创建一张表设置Mybatis配置文件 编写pojo实体类和mapper接口和mapper映射文件创建测试类总结前言 Mybatis算是...
    99+
    2024-04-02
  • springdata jpa如何使用Example快速实现动态查询功能
    这篇文章将为大家详细讲解有关springdata jpa如何使用Example快速实现动态查询功能,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。Example官方介绍Query by Example (Q...
    99+
    2023-06-25
  • 如何快速入门SQL Server XML查询
    本篇文章给大家分享的是有关如何快速入门SQL Server XML查询,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。sql xml 入门: -...
    99+
    2024-04-02
  • MYSQL JDBC快速查询响应的方法以及如何快速返回机制的实现
    MYSQL JDBC快速查询响应的方法以及如何快速返回机制的实现,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。 一直很纠结,...
    99+
    2024-04-02
  • 如何在Java PATH中快速查找JavaScript文件?
    Java作为一门强大的编程语言,不仅可以实现各种复杂的算法和数据结构,还能够与其他语言进行交互。在开发过程中,我们经常需要调用JavaScript代码,因此如何在Java PATH中快速查找JavaScript文件就成了一个重要的问题。 在...
    99+
    2023-08-23
    path javascript 文件
  • Go语言中的文件查找:如何使用Path索引文件实现快速定位?
    在现代计算机中,文件系统是操作系统中的一个重要组成部分。在文件系统中,文件的查找是一项非常常见的操作。Go语言中提供了一种高效的方式来索引文件——Path索引。本文将介绍如何使用Path索引文件实现快速定位。 什么是Path索引? Pat...
    99+
    2023-10-05
    path 索引 文件
  • C语言如何实现快速排序
    今天小编给大家分享一下C语言如何实现快速排序的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。交换排序的思想基本思想:所谓交换,...
    99+
    2023-07-02
  • C++如何实现数独快速求解
    这篇文章主要介绍“C++如何实现数独快速求解”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“C++如何实现数独快速求解”文章能帮助大家解决问题。什么是数独数独是源自18世纪瑞士的一种数学游戏。是一种运...
    99+
    2023-06-29
  • vbs如何实现文本文件编码查询工具
    这篇文章主要为大家展示了“vbs如何实现文本文件编码查询工具”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“vbs如何实现文本文件编码查询工具”这篇文章吧。代码如下:'QueryCode....
    99+
    2023-06-08
  • mybatisplus如何实现条件查询
    本篇内容介绍了“mybatisplus如何实现条件查询”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、wapper介绍用mp也可以方便的实...
    99+
    2023-06-30
  • 如何实现多条件查询
    这篇文章主要讲解了“如何实现多条件查询”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何实现多条件查询”吧! 而在对用户进行查...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作