在c#下遍历目录,应用最多的应该就是 System.IO.DirectoryInfo.GetDirectories或GetFiles了,但是当目录特别大,文件特别多时,效率不尽人意,此时我们很容易想到三个Win32API函数 FindFirstFile,FindNextFile和FindClose。这三个API搭配使用就能遍历文件和子目录了,而且可以遍历的时候随时中止,避免无谓的操作。在网上搜了一下,发现这方面的文章转载最多的应该就是http://www.cnblogs.com/xdesigner/archive/2006/12/08/586177.html  这篇了,但是按照文中描述的方法,并不能遍历子目录,没办法,就自己想办法,重新写了一个。

以下为源代码:

#region 声明WIN32API函数以及结构 **************************************
[Serializable,
System.Runtime.InteropServices.StructLayout
(System.Runtime.InteropServices.LayoutKind.Sequential,
CharSet = System.Runtime.InteropServices.CharSet.Auto
),
System.Runtime.InteropServices.BestFitMapping(false)]
private struct WIN32_FIND_DATA
{
public int dwFileAttributes;
public int ftCreationTime_dwLowDateTime;
public int ftCreationTime_dwHighDateTime;
public int ftLastAccessTime_dwLowDateTime;
public int ftLastAccessTime_dwHighDateTime;
public int ftLastWriteTime_dwLowDateTime;
public int ftLastWriteTime_dwHighDateTime;
public int nFileSizeHigh;
public int nFileSizeLow;
public int dwReserved0;
public int dwReserved1;
[System.Runtime.InteropServices.MarshalAs
(System.Runtime.InteropServices.UnmanagedType.ByValTStr,
SizeConst = 260)]
public string cFileName;
[System.Runtime.InteropServices.MarshalAs
(System.Runtime.InteropServices.UnmanagedType.ByValTStr,
SizeConst = 14)]
public string cAlternateFileName;
}
[System.Runtime.InteropServices.DllImport
("kernel32.dll",
CharSet = System.Runtime.InteropServices.CharSet.Auto,
SetLastError = true)]
private static extern IntPtr FindFirstFile(string pFileName, ref WIN32_FIND_DATA pFindFileData);
[System.Runtime.InteropServices.DllImport
("kernel32.dll",
CharSet = System.Runtime.InteropServices.CharSet.Auto,
SetLastError = true)]
private static extern bool FindNextFile(IntPtr hndFindFile, ref WIN32_FIND_DATA lpFindFileData);
[System.Runtime.InteropServices.DllImport("kernel32.dll", SetLastError = true)]
private static extern bool FindClose(IntPtr hndFindFile);
#endregion //具体方法函数 Stack<string> m_scopes = new Stack<string>();
private static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
WIN32_FIND_DATA FindFileData;
private System.IntPtr hFind = INVALID_HANDLE_VALUE;
void FindFileInDir(string rootDir)
{
string path = rootDir;
start:
new FileIOPermission(FileIOPermissionAccess.PathDiscovery, Path.Combine(path, ".")).Demand();
if (path[path.Length - 1] != '\\')
{
path = path + "\\";
}
Response.Write("文件夹为:"+path+"<br>");
hFind = FindFirstFile(Path.Combine(path,"*"), ref FindFileData);
if(hFind!=INVALID_HANDLE_VALUE)
{
do
{
if (FindFileData.cFileName.Equals(@".") || FindFileData.cFileName.Equals(@".."))
continue;
if ((FindFileData.dwFileAttributes & 0x10) != 0)
{
m_scopes.Push(Path.Combine(path, FindFileData.cFileName));
}
else
{
Response.Write(FindFileData.cFileName+"<br>");
}
}
while (FindNextFile(hFind, ref FindFileData));
}
FindClose(hFind);
if (m_scopes.Count > 0)
{
path = m_scopes.Pop();
goto start;
}
} //调用方法如下: FindFileInDir(@"D:");

c#调用api(FindFirstFile,FindNextFile)高效遍历目录文件【转载】的更多相关文章

  1. python遍历目录文件脚本的示例

    例子 自己写的一个Python遍历文件脚本,对查到的文件进行特定的处理.没啥技术含量,但是也记录一下吧. 代码如下 复制代码 #!/usr/bin/python# -*- coding: utf-8 ...

  2. ZH奶酪:PHP遍历目录/文件的3种方法

    其实PHP中内建函数scandir()就可以返回目录下全部文件和目录了... ========================== 1.使用$obj = dir($dir)返回目录对象$obj,然后使 ...

  3. linux 遍历目录+文件(优化版本)

    c++17 filesystem, regex 遍历目录 #include <stdio.h> #include <sys/types.h> #include <dire ...

  4. c++两种字符串赋值方式 并介绍 C语言下遍历目录文件的方式

    c++字符串声明:一种是声明字符数组并赋值,另一种是直接声明string类 #define _CRT_SECURE_NO_WARNINGS #include<iostream> #incl ...

  5. c++17 filesystem, regex 遍历目录

    linux 遍历目录+文件(优化版本) c++17 FS 还是挺好用的, VS2017支持,但是linux g++7.3 还是不支持 filesystem #include<filesystem ...

  6. windows 遍历目录下的所有文件 FindFirstFile FindNextFile

    Windows下遍历文件时用到的就是FindFirstFile 和FindNextFile 首先看一下定义: HANDLE FindFirstFile( LPCTSTR lpFileName, // ...

  7. Delphi调用API函数获取Windows目录信息、获取System目录信息、获取Temp临时文件目录信息

    var Str1, Str2: Array[..Max_Path]of Char;//开辟缓冲区 Str3: Array[..]of Char; begin GetWindowsDirectory(@ ...

  8. 在Linux下和Windows下遍历目录的方法及如何达成一致性操作

    最近因为测试目的需要遍历一个目录下面的所有文件进行操作,主要是读每个文件的内容,只要知道文件名就OK了.在Java中直接用File类就可以搞定,因为Java中使用了组合模式,使得客户端对单个文件和文件 ...

  9. C/C++遍历目录下的所有文件(Windows篇,超详细)

    注: 1. 本文讨论的是怎么用Windows API遍历目录下的所有文件.除Windows API,还有一种Windows/Linux通用的方式,使用<io.h>. 2. 本文部分翻译自M ...

随机推荐

  1. Ionic简介和环境安装

    什么是Ionic Ionic是一个用来开发混合手机应用的,开源的,免费的代码库.可以优化html.css和js的性能,构建高效的应用程序,而且还可以用于构建Sass和AngularJS的优化.ioni ...

  2. C# 两时间,时间间隔

    #region 返回时间差        public static string DateDiff(DateTime DateTime1, DateTime DateTime2)        {  ...

  3. KEIL4.12中添加ULINK2的支持

    转载自:http://www.amobbs.com/thread-4767650-1-1.html 如果你用KEIL4.12,但却没有Ulink2下载器,只有早先用的Ulink下载器,那么你按照下面三 ...

  4. IP工具类——IpAddress.java

    根据IP地址获取详细的地域信息,也可通过 http://whois.pconline.com.cn/ 获取地址信息. 源码如下:(点击下载  IpAddress.java) import java.i ...

  5. Logstash同步Oracle数据到ElasticSearch

    最近在项目上应用到了ElasticSearch和Logstash,在此主要记录了Logstash-input-jdbc同步Oracle数据库到ElasticSearch的主要步骤,本文是对环境进行简单 ...

  6. DDD领域驱动设计和实践(转载)

    -->目录导航 一. DDD领域驱动设计介绍 1. 什么是领域驱动设计(DDD) 2. 领域驱动设计的特点 3. 如果不使用DDD? 4. 领域驱动设计的分层架构和构成要素 5. 事务脚本和领域 ...

  7. 关于后缀数组的倍增算法和height数组

    自己看着大牛的论文学了一下后缀数组,看了好久好久,想了好久好久才懂了一点点皮毛TAT 然后就去刷传说中的后缀数组神题,poj3693是进化版的,需要那个相同情况下字典序最小,搞这个搞了超久的说. 先简 ...

  8. laravel 框架学习资料

    demo:http://forumsarchive.laravel.io/viewtopic.php?id=3536 使用Laravel和Angular创建一个单页的评论应用 http://devel ...

  9. asp.net中bin目录下的 dll.refresh文件

    首先找到了这篇文章http://www.cnblogs.com/haokaibo/archive/2010/07/31/1789342.html 然后找到一篇英文的文章http://monsur.xa ...

  10. SQL Server 2008 远程过程调用失败[ VS2012]

    查看SQL Server配置管理工具,SQL Server 2008 服务中提示“远程过程调用失败”. [解决办法] 首先,核查用户名密码是否正确. 其次,查看sql server 配置管理器中,第一 ...