在c#下遍歷目錄,應用最多的應該就是 System.IO.DirectoryInfo.GetDirectories或GetFiles了,但是當目錄特別大,文件特別多時,效率不盡人意,此時我們很容易想到三個Win32API函數 FindFirstFile,FindNextFile和FindClose。這三個API搭配使用就能遍歷文件和子目錄吧,這篇了,但是按照文中描述的方法,並不能遍歷子目錄,沒辦法,就自己想辦法,重新寫了一套。
以下為源代碼:
[csharp]
#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:");
作者:love_rrr