在某些情況下,會有使用長路徑(大於MAX_PATH/260字符)的需求,如網絡文件管理之類的,WindowsNT之後的NTFS文件系統其實是支持這樣的操作的,但需求畢竟比較特殊,而且Explorer資源瀏覽器都不支持它,所以很少被認識到.
這裏我寫了一個子目遞歸調用函數,原型:
INT32 LongPathFileFind(LPWSTR lpPath, //被搜索路徑
IfFindAFile fIfFind, //搜到子文件時的回調
INT32 nFindMode) //是否遞歸方式
IfFindAFile 定義:
typedef INT32 (CALLBACKFUNC *IfFindAFile)(LPWSTR lpFileName, //找出的文件名
INT32 nFindCount); //文件的序號
使用它們就可以在32767字符長度的目錄之中自由穿梭了。
測試代碼在VC7下運行成功,AddASubDir測試回調功能是加入子目錄,注意這樣會無限的生成子目錄,不需要這樣的話,請停止運行。
實例代碼如下:
//TtestLongPathFind.cpp
#include "stdafx.h"
#define LONG_FIND_SUCCSS 0
#define LONG_FIND_ERROR_FIRST -2
#define CALLBACKFUNC __stdcall
#define FIND_MODE_RECURSIVE 0x01
typedef INT32 (CALLBACKFUNC *IfFindAFile)(LPWSTR lpFileName, INT32 nFindCount);
INT32 CALLBACKFUNC AddASubDir(LPWSTR lpFileName, INT32 nFindCount)
{
WCHAR *pszCreatePathName = new WCHAR[1024 * 1024];
wsprintfW(pszCreatePathName, L"%s//asdfasdfasdf", lpFileName);
if(CreateDirectoryW(pszCreatePathName, NULL) == FALSE)
{
delete[] pszCreatePathName;
return -1;
}
delete[] pszCreatePathName;
return 0;
}
INT32 LongPathFileFind(LPWSTR lpPath, IfFindAFile fIfFind, INT32 nFindMode)
{
WIN32_FIND_DATAW WFD;
HANDLE hFileFind;
INT32 nRet = LONG_FIND_SUCCSS;
WCHAR *pszFindFile = new WCHAR[1024 * 1024];
WCHAR *pszFileFullPath = new WCHAR[1024 * 1024];
while(TRUE)
{
wsprintfW(pszFindFile, L"%s//*", lpPath);
hFileFind = ::FindFirstFileW(pszFindFile, &WFD);
INT32 nFileCount = 0;
if( hFileFind == INVALID_HANDLE_VALUE )
{
nRet = LONG_FIND_ERROR_FIRST;
break;
}
do
{
if(::FindNextFileW(hFileFind, &WFD) == FALSE)
break;
if(WFD.cFileName[0] != L"."[0])
{
wsprintfW(pszFileFullPath, L"%s//%s", lpPath, WFD.cFileName);
fIfFind(pszFileFullPath, nFileCount);
if(nFindMode == FIND_MODE_RECURSIVE)
{
if(WFD.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
LongPathFileFind(pszFileFullPath, fIfFind, nFindMode);
}
}
}
nFileCount++;
}while(TRUE);
::FindClose(hFileFind);
}
delete[] pszFindFile;
return nRet;
}
int _tmain(int argc, _TCHAR* argv[])
{
WCHAR *pszPathName = new WCHAR[1024 * 1024];
wsprintfW(pszPathName, L"%s", L"////?//C://Test");
INT32 nCount = 0;
LongPathFileFind( pszPathName , AddASubDir, FIND_MODE_RECURSIVE);
delete[] pszPathName;
return 0;
}