下面的c#.net控制臺應用程式只顯示了D盤中的檔案夾名稱,而沒有顯示完整的路徑名稱,但我想在win32 API的幫助下在檔案夾、子檔案夾和這些子檔案夾中的檔案中進行遞回迭代,因為我必須掃描有成千上萬檔案的檔案夾。 Win32 API作業速度很快,所以我沒有使用普通的c#.net函式來獲取目錄及其檔案。
class Program<
{
//Kernal32.dll匯入用于檔案管理操作。
[DllImport("kernel32.dll"/span>, SetLastError = true, CharSet = CharSet.Unicode)]
public static extern IntPtr FindFirstFileEx()
string lpFileName,
FINDEX_INFO_LEVELS fInfoLevelId,
out WIN32_FIND_DATA lpFindFileData。
FINDEX_SEARCH_OPS fSearchOp,
IntPtr lpSearchFilter。
int dwAdditionalFlags)。
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
static extern bool FindNextFile(IntPtr hFindFile, out WIN32_FIND_DATA lpFindFileData)。
[DllImport("kernel32.dll")]
static extern bool FindClose(IntPtr hFindFile) 。
public const int FIND_FIRST_EX_CASE_SENSITIVE = 1;
public const int FIND_FIRST_EX_LARGE_FETCH =2;
static void Main()
{
WIN32_FIND_DATA findData。
FINDEX_INFO_LEVELS findInfoLevel = FINDEX_INFO_LEVELS.FindExInfoBasic;
int additionalFlags = 0;
if (Environment.OSVersion.Version.Major >= 6)
{
findInfoLevel = FINDEX_INFO_LEVELS.FindExInfoBasic;
//additionalFlags = FIND_FIRST_EX_LARGE_FETCH;。
}
string pattern = "D:*.*"/span>;
IntPtr hFile = FindFirstFileEx(
模式。
findInfoLevel,
out findData,
FINDEX_SEARCH_OPS.FindExSearchNameMatch,
IntPtr.Zero,
additionalFlags)。)
int error = Marshal.GetLastWin32Error()。
if (hFile.ToInt32() != 1)
{
do (hFile.ToInt32()!
{
Console.WriteLine("Found file {0}, & Attribute is {1}", findData.cFileName, findData.dwFileAttributes) 。
}
while (FindNextFile(hFile, out findData)) 。
FindClose(hFile)。
}
Console.ReadLine()。
}
}
下面是程式所需的列舉和結構。
public enum FINDEX_SEARCH_OPS
{
FindExSearchNameMatch = 0,
FindExSearchLimitToDirectories = 1,
FindExSearchLimitToDevices = 2.
}
public enum FINDEX_INFO_LEVELS
{
FindExInfoStandard = 0,
FindExInfoBasic = 1.
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
struct WIN32_FIND_DATA
{
public uint dwFileAttributes;
public System.Runtime.InteropServices.ComTypes.FILETIME ftCreationTime;
public System.Runtime.InteropServices.ComTypes.FILETIME ftLastAccessTime;
public System.Runtime.InteropServices.ComTypes.FILETIME ftLastWriteTime;
public uint nFileSizeHigh;
public uint nFileSizeLow;
public uint dwReserved0;
public uint dwReserved1;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string cFileName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
public string cAlternateFileName;
}
我得到了代碼來自Pinvoke.net。 net 和網站是 http://pinvoke.net/。
uj5u.com熱心網友回復:
你可以把你的代碼放到一個rekursive函式中,并為每個檔案夾呼叫它:
static void Main()
{
WIN32_FIND_DATA findData。
FINDEX_INFO_LEVELS findInfoLevel = FINDEX_INFO_LEVELS.FindExInfoBasic;
int additionalFlags = 0;
if (Environment.OSVersion.Version.Major >= 6)
{
findInfoLevel = FINDEX_INFO_LEVELS.FindExInfoBasic;
//additionalFlags = FIND_FIRST_EX_LARGE_FETCH;。
}
string startFolder = @"D:"/span>;
var watch = new Stopwatch()。
watch.Start();
IterateFolder(findInfoLevel, additionalFlags, startFolder)。
watch.Stop()。
Console.WriteLine()。
Console.WriteLine($"{watch.Elapsed.TotalSeconds}")。
Console.ReadLine()。
}
public const uint FILE_ATTRIBUTE_DIRECTORY =0x10;
private static void IterateFolder(FINDEX_INFO_LEVELS findInfoLevel, int additionalFlags, string folder)?
{
WIN32_FIND_DATA findData;
IntPtr hFile = FindFirstFileEx(
$"{folder}*.*"/span>,
findInfoLevel,
out findData,
FINDEX_SEARCH_OPS.FindExSearchNameMatch,
IntPtr.Zero,
additionalFlags)。)
int error = Marshal.GetLastWin32Error()。
if (hFile.ToInt32() != 1)
{
do (hFile.ToInt32()!
{
if (findData.cFileName == "." || findData.cFileName == " .") 繼續;//ignore folder navigation。
var foundFolder = $"{folder}{findData.cFileName}"/span>。
Console.WriteLine("發現檔案{0}, & 屬性是{1}", foundFolder, findData.dwFileAttributes)。
if ((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) > 0)
{
/Recursive for directories[/span]。
IterateFolder(findInfoLevel, additionalFlags, foundFolder)。
}
}
while (FindNextFile(hFile, out findData))。
FindClose(hFile)。
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/320308.html
標籤:
上一篇:VBA中的StringFromIID-有什么好辦法可以避免手動管理記憶體?
下一篇:從一個冒名頂替的執行緒創建行程
