VC遍历文件夹下所有文件和文件夹等技巧

本文详细介绍了如何获取本机IP地址,并通过C++实现文件路径选择、遍历文件夹、文件查找及处理的技术。涵盖了从基础概念到实际应用的全过程,包括使用对话框、线程、文件信息结构体等高级功能,旨在提供丰富的实践经验和深入的理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文地址:点击打开链接

1.获取本机的IP地址

#i nclude <stdio.h>

#i nclude <winsock2.h>

#pragma comment (lib, “ws2_32.lib”)

Void CheckIP() {

   WSADATA wsadata;

Char name[155];

Char *ip;

PHOSTENT hostinfo;

If (WSAStartUp( MAKEWORD(2,0), &wsadate) = = 0) {

     If ( gethostname( name, sizeof(name)) = = 0) {

         If((hostinfo = gethostbyname(name)) != NULL) {//获得IP的函数

             Ip = inet_ntoa(*(struct in_addr*)*hostinfo -> h_addr_list);

             Printf*”%s"n”, ip); } }

WSACleanup(); }    }

 

2. CWnd:: SetDlgItemInt(); 被对话框设定一个由字符串表示的整型值。

   CSemaphore ---à CSyncObject------àCObject

     在一个进程或多个进程中允许访问一种资源的允许线程数,CSemaphore对象维持当前获取一种指定资源的线程个数。当计数大于0时,Semaphore对象的状态是有信号状态;典型应用是用Semaphore去限制使用一种资源的线程个数。用WaitforSingleObject等待有信号状态,返回时则减少对Semaphore的计数。

3. 得到计算机所有驱动函数GetAllDriverList()

     CString tmp = _T(“A:""”), dir;

     for(int i=1; i<=25; i++) {

          dir = CString(‘A’+i)+ _T(“:""”);

          if(GetDriveType(dir.GetBuffer(0)) = = DRIVE_NO_ROOT_DIR) continue;

          tmp += “;” + dir; }

     return tmp;

4. 打开对话框,选择文件路径函数 OnBrowse()

BROWSEINFO bi;

char dispname[MAX_PATH], path[MAX_PATH];

ITEMIDLIST    *pidl;

bi.hwndOwner = m_hWnd;

bi.pidlRoot = 0;

bi.pszDisplayName = dispname;

bi.ulFlags = BIF_RETUREONLYFSDIRS | BIF_EDITBOX | BIF_DONTGOBELOWDOMAIN;

bi.lpfn = 0;

bi.lParam = 0;

bi.iImage = 0;

if(pidl = SHBrowseForFolder(&bi)) { //显示一个使用用户可以选择的文件打开对话框

 SHGetPathFromIDList(pidl, path); //把一个item identifier list转化为一个文件系统路径

 m_folder = CString(path);

 if(m_folder.IsEmpty() )   m_folder = GetAllDirverList();

 UpdateData(FALSE); }

SHGetFileInfo(); 返回文件系统中对象的信息,比如文件、folder、路径、驱动器

 

5. 如何使用CImageList 

CImageList m_iImageList;

m_iImageList.Create(24,24,TRUE,1,0);

HICON hIcon = NULL;

hIcon = (HICON)::LoadImage(::AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_KEBIAO0, IMAGE_ICON,24,24,0);

m_iImageList.Add(hIcon);

m_FileTree.SetImageList(&m_iImageList, TVSIL_NORMAL); //m_FileTree为TreeList控件

//或者这样来创建:

m_imageList.DeleteImageList();

m_image.Create(16,16,ILC_COLORDDB,1,100);

m_listCtrl.SetImageList(&m_iImageList, LVSIL_SMALL);

6. 遍历一个文件夹的文件

OnFindFile(WPARAM wParam, LPARAM lParam) {

 CString strFilePath = *((CString*)wParam);

 if(strFilePath.Right(1) != “""”) {

     strFilePath +=”""”; }

strFilePath += “*.*”;

CFileFind   finder;

CString strFileName;

BOOL isHave = finder.FindFile(strFilePath);

while(isHave) {

     isHave = finder.FindNextFile();

     if(!finder.IsDirectory() && !finder.IsDots()) {

         strFileName = finder.GetFilePath();

         :: PostMessage((HWND)(GetMainWnd()->GetSafeHWnd()), WM_DISPLAY, (WPARAM)&strFileName, NULL); }

finder.Close();   }

7. 如何来启动这个查找线程

新建一个类派生于CWinThread;CFindFileThread *pFindFileThread;

pFindFileThread = (CFindFileThread*)AfxBeginThread(RUNTIME_CLASS(CFindFileThread);

pFindFileThread -> PostThreadMessage(WM_FINDFILE, (WPARAM)&strFilePath,NULL);

 

8. 找到一个则发送消息WM_DISPLAY,并把文件中全路径作为参数返回

     获取一个文件的信息 OnDisplay(WPARAM wParam, LPARAM lParam) {

     count++; //统计文件个数

     CString strFileName = *((CString*)wParam);

     CFileStatus status;

     C: GetStatus(strFileName, status);

     CString unit = “Byte”;

     float flen = (float)status.m_size;

     if(flen>1024) {

           flen /= 1024;

           if(flen < 1024)   unit = “KB”;

           else {

                flen /= 1024;

                unit = “MB”; } }

      CString size;

      size.Format(“%1.2f”, flen);

      int pos = strFileName.ReverseFind(‘""’);

      SHFILEINFO sfi; //文件信息结构体

      if(:: SHGetFileInfo(strFileName, FILE_ATTRIBUTE_NORMAL, &sfi,

         Sizeof(SHFILEINFO), SHGFI_USEFILEATTRIBUTES |

          SHGFI_DISPLAYNAME | SHGFI_TYPENAME | SHGFI_ICON

              | SHGFI_SMALLICON)) {

            m_imgList.Add(sfi.hIcon);

            m_filelist.InsertItem(count-1, sfi.szDisplayName, count-1);

            m_filelist.SetItemText(count-1, 1, strFileName, Mid(0,pos));

          m_filelist.SetItemText(count-1, 2, (size+unit));

          m_filelist.SetItemText(count-1, 3, sfi.szTypeName); }

     m_filelist.Update(count-1); }

 

9. 在图片中隐藏信息的做法:加社会图片文件为c:"s.jpg, 文字为d:"w.txt, 在命令行方式窗口中输入命令  COPY /B C:"s.jpg + d:"w.txt   c:"d.jpg

10. 获得应用程序所在路径

char szCurPath[_MAX_PATH];

HINSTANCE hInst = NULL;

GetMoudleFileName( hInst, szCurPath, _MAX_PATH); //获得应用程序所在路径

char *p = szCurPath;

while( strchr(p, ‘""’)) {

      p= strchr( p, ‘""’);

      p++; }

*p = ‘"0’;

ShellExecute(NULL, NULL, _T(“Your.exe”), NULL, _T(szCurPath), SW_SHOWNORMAL);

 

总结问题的解决方法,有助于获得更多的实战经验,不断地积累,在编程方面就会有长足的进步~!

学习的过程是一个不断积累的过程,只有学习的时间累积到一定的程度,才能发生质的提高。。。


 |字号 订阅

finddata_t的使用

  那么到底如何查找文件呢?我们需要一个结构体和几个大家可能不太熟悉的函数。这些函数和结构体在<io.h>的头文件中,结构体为 struct _finddata_t ,函数为_findfirst、_findnext和_fineclose.具体如何使用,我会慢慢讲来~

  首先讲这个结构体吧~struct _finddata_t ,这个结构体是用来存储文件各种信息的。说实话,这个结构体的具体定义代码,我没有找到,不过还好,文档里面在_find里有比较详细的成员变量介绍。我基本上就把文档翻译过来讲吧:

  unsigned atrrib:文件属性的存储位 置。它存储一个unsigned单元,用于表示文件的属性。文件属性是用位表示的,主要有以下一些:_A_ARCH(存档)、_A_HIDDEN(隐 藏)、_A_NORMAL(正常)、_A_RDONLY(只读)、_A_SUBDIR(文件夹)、_A_SYSTEM(系统)。这些都是 在<io.h>中定义的宏,可以直接使用,而本身的意义其实是一个无符号整型(只不过这个整型应该是2的几次幂,从而保证只有一位为1,而其 他位为0)。既然是位表示,那么当一个文件有多个属性时,它往往是通过位或的方式,来得到几个属性的综合。例如只读+隐藏+系统属性,应该 为:_A_HIDDEN | _A_RDONLY |_A_SYSTEM .

  time_t time_create:这里的time_t是一个变量类型(长整型?相当于long int?),用来存储时间的,我们暂时不用理它,只要知道,这个time_create变量是用来存储文件创建时间的就可以了。

  time_t time_access:文件最后一次被访问的时间。

  time_t time_write:文件最后一次被修改的时间。

  _fsize_t size:文件的大小。这里的_fsize_t应该可以相当于unsigned整型,表示文件的字节数。

  char name[_MAX_FNAME]:文件的文件名。这里的_MAX_FNAME是一个常量宏,它在<stdlib.h>头文件中被定义,表示的是文件名的最大长度。

  以此,我们可以推测出,struct_finddata_t ,大概的定义如下:

  struct _finddata_t

  {

  unsigned attrib;

  time_t time_create;

  time_t time_access;

  time_t time_write;

  _fsize_t size;

  char name[_MAX_FNAME];

  };

  前面也说了,这个结构体是用来存储文件信息的,那么如何把一个硬盘文件的文件信息“存到”这个结构体所表示的内存空间里去呢?这就要靠_findfirst、_findnext和_fineclose三个函数的搭配使用了。

  首先还是对这三个函数一一介绍一番吧……

  long _findfirst( char *filespec, struct _finddata_t *fileinfo );

  返回值:如果查找成功的话,将返回一个long型的唯一的查找用的句柄(就是一个唯一编号)。这个句柄将在_findnext函数中被使用。若失败,则返回-1.

  参数:

  filespec:标明文件的字符串,可支持通配符。比如:*.c,则表示当前文件夹下的所有后缀为C的文件。

  fileinfo :这里就是用来存放文件信息的结构体的指针。这个结构体必须在调用此函数前声明,不过不用初始化,只要分配了内存空间就可以了。函数成功后,函数会把找到的文件的信息放入这个结构体中。

  int _findnext( long handle, struct _finddata_t *fileinfo );

  返回值:若成功返回0,否则返回-1.

  参数:

  handle:即由_findfirst函数返回回来的句柄。

  fileinfo:文件信息结构体的指针。找到文件后,函数将该文件信息放入此结构体中。

  int _findclose( long handle );

  返回值:成功返回0,失败返回-1.

  参数:

  handle :_findfirst函数返回回来的句柄。

  大家看到这里,估计都能猜到个大概了吧?先用_findfirst查找第一个文件,若成功则用返回的句柄调用_findnext函数查找其他的 文件,当查找完毕后用,用_findclose函数结束查找。恩,对,这就是正确思路。下面我们就按照这样的思路来编写一个查找C:\WINDOWS文件 夹下的所有exe可执行文件的程序。

  #include <stdio.h>

  #include <io.h>

  const char *to_search="C:\\WINDOWS\\*.exe";        //欲查找的文件,支持通配符

  int main()

  {

  long handle;                                               //用于查找的句柄

  struct _finddata_t fileinfo;                          //文件信息的结构体

  handle=_findfirst(to_search,&fileinfo);         //第一次查找

  if(-1==handle)return -1;

  printf("%s\n",fileinfo.name);                         //打印出找到的文件的文件名

  while(!_findnext(handle,&fileinfo))               //循环查找其他符合的文件,知道找不到其他的为止

  {

  printf("%s\n",fileinfo.name);

  }

  _findclose(handle);                                      //别忘了关闭句柄

  system("pause");

  return 0;

  }

  当然,这个文件的查找是在指定的路径中进行,如何遍历硬盘,在整个硬盘中查找文件呢?大家可以在网络上搜索文件递归遍历等方法,这里不再做进一步介绍。

  细心的朋友可能会注意到我在程序的末尾用了一个system函数。这个与程序本身并没有影响,和以前介绍给大家的使用getchar()函数的 作用相同,只是为



一、先介绍一个结构WIN32_FIND_DATA

typedef struct _WIN32_FIND_DATA

{

DWORD dwFileAttributes; //文件属性

FILETIME ftCreationTime; // 文件创建时间

FILETIME ftLastAccessTime; // 文件最后一次访问时间

FILETIME ftLastWriteTime; // 文件最后一次修改时间

DWORD nFileSizeHigh; // 文件长度高32

DWORD nFileSizeLow; // 文件长度低32

DWORD dwReserved0; // 系统保留

DWORD dwReserved1; // 系统保留

TCHAR cFileName[ MAX_PATH ]; // 长文件名

TCHAR cAlternateFileName[ 14 ]; // 文件的可选名

} WIN32_FIND_DATA;

可以通过FindFirstFile()函数,根据文件路径把待操作文件的相关属性读取到WIN32_FIND_DATA结构中去:

WIN32_FIND_DATA ffd;

HANDLE hFind = FindFirstFile("c://test.dat",&ffd);

二、函数FindFirstFile

   1、声明:HANDLE FindFirstFile(LPCTSTR lpFileName,LPWIN32_FIND_DATA lpFindFileData);

2、参数:

lpFileName String,欲搜索的文件名。可包含通配符,并可包含一个路径或相对路径名

lpFindFileData WIN32_FIND_DATA,一个WIN32_FIND_DATA指针,用于装载与找到的文件有关的信息,该结构可用于后续的搜索

3、返回值:

如执行成功,返回一个搜索句柄。如果出错,返回一个INVALID_HANDLE_VALUE常数,一旦不再需要,应该用FindClose函数关闭这个句柄

4、功能

读取文件信息到一个WIN32_FIND_DATA结构中,返回这个文件的句柄

5、注释:

由这个函数返回的句柄可以作为一个参数用于FindNextFile函数。这样一来,就可以方便的枚举出与lpFileName参数指定的文件名相符的所有文件(是指文件名含有通配符)

三、函数FindNextFile

1、声明BOOL FindNextFile(HANDLE hFindFile, LPWIN32_FIND_DATA lpFindFileData);

2、参数:

HANDLE hFindFile搜索的文件句柄,函数执行的时候搜索的是此句柄的下一文件

LPWIN32_FIND_DATA lpFindFileData一个WIN32_FIND_DATA指针,

3、返回值:

如果调用成功返回一个非0值;调用失败,返回为0,可调用GetLastError来获取错误信息

4、功能

继续查找FindFirstFile函数搜索后的文件

5、注释:

这个函数可以连续调用,以方便的枚举出与lpFileName参数指定的文件名相符的所有文件

 

四、下面是遍历代码

#include<windows.h>
#include<iostream>
#include<string>
using namespace std;

//只能处理目录:lpPath只能是路径

 

 

find(char * lpPath)
{
char szFind[MAX_PATH];
WIN32_FIND_DATA FindFileData;
strcpy(szFind,lpPath);
strcat(szFind,"*.*");
HANDLE hFind=::FindFirstFile(szFind,&FindFileData);
if(INVALID_HANDLE_VALUE == hFind)return;
while(TRUE)
{
if(FindFileData.dwFileAttributes

&FILE_ATTRIBUTE_DIRECTORY)
{
if(FindFileData.cFileName[0]!='.')
{
strcpy(szFile,lpPath);
strcat(szFile,"");
strcat(szFile,FindFileData.cFileName);
find(szFile);
}
}
else
{
cout << FindFileData.cFileName;
}
if(!FindNextFile(hFind,&FindFileData))break;
}
FindClose(hFind);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值