1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 没看到能打的 遍历目录并读取目录下的文件列表。(C语言 SDK)

没看到能打的 遍历目录并读取目录下的文件列表。(C语言 SDK)

时间:2021-07-23 03:28:39

相关推荐

没看到能打的 遍历目录并读取目录下的文件列表。(C语言 SDK)

遍历目录并读取目录下的所有文件,这个功能经常用,也简单,很多年前就看过网上的代码,感觉写复杂了,而且还浪费栈,发文的人说会“爆栈”(而且还不是一个人)。当时看到那些代码就觉得写的不好,不过觉得无关痛痒没有发博文。

N年过去,遇到类似的情况,有点忍不住,这么简单的东西。今天专门去搜索了网上(摆渡和谷歌上面的代码,包括StackOverflow上面的代码,不禁说出周星星电影《破坏之王》里面断水流大师兄的那段话。

找到的代码,几乎都是类似的,代码长,真浪费内存,速度又慢,还没有错误判断。

找一个稍好的例子。

bool ListDirectoryContents(const wchar_t *sDir)

{

WIN32_FIND_DATA fdFile;

HANDLE hFind = NULL;

wchar_t sPath[2048];

//Specify a file mask. *.* = We want everything!

wsprintf(sPath, L"%s\\*.*", sDir);

if((hFind = FindFirstFile(sPath, &fdFile)) == INVALID_HANDLE_VALUE)

{

wprintf(L"Path not found: [%s]\n", sDir);

return false;

}

do

{

//Find first file will always return "."

// and ".." as the first two directories.

if(wcscmp(fdFile.cFileName, L".") != 0

&& wcscmp(fdFile.cFileName, L"..") != 0)

{

//Build up our file path using the passed in

// [sDir] and the file/foldername we just found:

wsprintf(sPath, L"%s\\%s", sDir, fdFile.cFileName);

//Is the entity a File or Folder?

if(fdFile.dwFileAttributes &FILE_ATTRIBUTE_DIRECTORY)

{

wprintf(L"Directory: %s\n", sPath);

ListDirectoryContents(sPath); //Recursion, I love it!

}

else{

wprintf(L"File: %s\n", sPath);

}

}

}

while(FindNextFile(hFind, &fdFile)); //Find the next file.

FindClose(hFind); //Always, Always, clean things up!

return true;

}

网上的都是类似的,还有说遍历复杂云云,其实不复杂,代码短并且省内存(这里主要是省栈),速度更快。

这样写的时候,想想就发现,有两个地方可以优化,第一,局部变量sPath,这里占用内存大,而且还每次都复制一次,速度慢;第二、局部变量fdFile,这个占用内存也大......

又大又慢,所以会爆栈。

我现在记事本写一个比这个好的(N年前就这么写了,还有牛人说不需要递归,当时想了一下,我也实现了)。

UINT ListFiles(const TCHAR *pathname, UINT pathnamelength, UINT pathnamesize, WIN32_FIND_DATA *pfd)

{

HANDLE hfind;

UINT l;

UINT result = 0;

if (pathnamelength > 0 && pathname[pathnamelength - 1] != _T('\\'))

{

pathname[pathnamelength++] = _T('\\');

}

pathname[pathnamelength+0] = _T('*');

pathname[pathnamelength+1] = _T('.');

pathname[pathnamelength+2] = _T('*');

pathname[pathnamelength+3] = _T('\0');

hfind =FindFirstFile(pathname, pfd);

if(hfind != INVALID_HANDLE_VALUE)

{

do

{

// 这里可以优化的,留给有追求的人优化,不过这里不是关键

if(_tcscmp(pfd->cFileName, _T(".")) != 0&& _tcscmp(pfd->cFileName, _T("..")) != 0)

{

l = _tcslen(pfd->cFileName);

// 避免越界

if (pathnamelength + l < pathnamesize)

{

// 重用了占用内存的pathname和pfd

_tcscpy(pathname + pathnamelength, pfd->cFileName);

// 已经获取了文件信息,爱干嘛干嘛去

if(pfd->dwFileAttributes &FILE_ATTRIBUTE_DIRECTORY)

{

result +=ListFiles(pathname, pathnamelength + l, pathnamesize, pfd);

}

else{

result++;

}

}

}

}while(FindNextFile(hfind, pfd));

FindClose(hfind);

}

return (result);

}

我在网上看到linux下遍历的代码也大同小异,也没有优化,都可以类似这么写的。

不骄傲,一个小代码而已,N年前就会这么写了。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。