您的位置:首页 > 编程语言 > C语言/C++

如何用C语言清空特定文件夹中的所有文件

2011-10-17 19:04 323 查看
一、准备知识

1、WIN32_FIND_DATA数据结构

WIN32_FIND_DATA结构描述了一个由FindFirstFile, FindFirstFileEx, 或FindNextFile函数查找到的文件信息。

结构内容如下:

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 ]; // 8.3格式文件名

  } WIN32_FIND_DATA, *PWIN32_FIND_DATA;

(8.3格式:通常指较旧的Windows操作系统或DOS的文件命名限制,8指文件名最大长度为8,3指扩展名最大长度为3,若不符合以上限制则会以"~"作延长名称如"Program Files"会变成"Progra~1",若同一文件夹有相似的名称,末端的数值则会自动递增)

2、HANDLE句柄

从广义上,能够从一个数值拎起一大堆数据的东西都可以叫做句柄。指针其实也是一种"句柄",只是由于指针同时拥有更特殊的含义——实实在在地对应内存里地一个地址——所以,通常不把指针说成是"句柄"。但指针也有着能从一个32位的值引用到一大堆数据的作用,这不是句柄又是什么?

Windows系统中有许多内核对象(这里的对象不完全等价于"面向对象程序设计"一词中的"对象",虽然实质上还真差不多),比如打开的文件,创建的线程,程序的窗口,等等。这些重要的对象肯定不是4个字节或者8个字节足以完全描述的,他们拥有大量的属性。为了保存这样一个"对象"的状态,往往需要上百甚至上千字节的内存空间,那么怎么在程序间或程序内部的子过程(函数)之间传递这些数据呢?拖着这成百上千的字节拷贝来拷贝去吗?显然会浪费效率。

那么怎么办?当然传递这些对象的首地址是一个办法,但这至少有两个缺点:

a、暴露了内核对象本身,使得程序(而不是操作系统内核)也可以任意地修改对象地内部状态(首地址都知道了,还有什么不能改的?),这显然是操作系统内核所不允许的;

b、操作系统有定期整理内存的责任,如果一些内存整理过一次后,对象被搬走了怎么办?

所以,Windows操作系统就采用进一步的间接:在进程的地址空间中设一张表,表里头专门保存一些编号和由这个编号对应一个地址,而由那个地址去引用实际的对象,这个编号跟那个地址在数值上没有任何规律性的联系,纯粹是个映射而已。在Windows系统中,这个编号就叫做"句柄"。

Handle在Windows中的含义很广泛,以下关于谈到的Handle除非特别说明,将仅限于进程、线程的上下文中。

Handle本身是一个32位的无符号整数,它用来代表一个内核对象。它并不指向实际的内核对象,用户模式下的程序永远不可能获得一个内核对象的实际地址(一般情况下)。那么Handle的意义何在?它实际上是作为一个索引在一个表中查找对应的内核对象的实际地址。那么这个表在哪里呢?每个进程都有这样的一个表,叫句柄表。该表的第一项就是进程自己的句柄,这也是为什么你调用GetCurrentProcess()总是返回0x7FFFFFFF原因。

简单地说,Handle就是一种用来"间接"代表一个内核对象的整数值。你可以在程序中使用handle来代表你想要操作的内核对象。这里的内核对象包括:事件(Event)、线程、进程、Mutex等等。我们最常见的就是文件句柄(file handle)。

3、FindFirstFile函数

函数功能:一个文件夹(包括子文件夹)去搜索指定文件

函数的参数:

a、LPCTSTR lpFileName :文件名

b、LPWIN32_FIND_DATA lpFindFileData:数据缓冲区(传WIN32_FIND_DATA结构体对象的地址)

函数的返回值:

如果调用成功返回一个句柄,可用来做为FindNextFile函数和FindClose函数的参数。调用失败 返回为INVALID_HANDLE_VALUE(即-1) ,可调用GetLastError函数来获取错误信息。

4、FindNextFile函数

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

函数的参数:

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

b、LPWIN32_FIND_DATA lpFindFileData:指向一个用于保存文件信息的结构体(传WIN32_FIND_DATA结构体对象的地址)

函数的返回值:

非零表示成功,零表示失败。如不再有与指定条件相符的文件,会将GetLastError设置成ERROR_NO_MORE_FILES

5、FindClose函数

函数功能:关闭FindFirstFile创建的搜索句柄

函数的参数:

HANDLE hFindFile:搜索句柄

函数的返回值:

调用成功 返回一个非0值,失败 返回0 可利用GetLastError来得到错误信息。

二、清空特定文件夹中的所有文件

#include<iostream>

#include<fstream>

#include<string>

using namespace std;

#include<windows.h>

#include<shellapi.h>

int main()

{

char *a=".";

char *b="";

WIN32_FIND_DATA FileData,FileData_0;//创建WIN32_FIND_DATA数据结构对象

HANDLE hSearch,hSearch_0;

BOOL fFinished=FALSE;

hSearch=FindFirstFile("C:\\Documents and Settings\\mingyang\\Desktop\\maps_files\\*.*",&FileData);

if(hSearch==INVALID_HANDLE_VALUE)

{

cout<<"No files found!"<<endl;

return 0;

}

while(!fFinished)

{

if(FileData.cFileName[0]!=a[0])

{

b=FileData.cFileName;

string addr=string("C:\\Documents and Settings\\mingyang\\Desktop\\maps_files\\")+string(b)+string("\\")+string("*.*");

hSearch_0=FindFirstFile(addr.c_str(),&FileData_0);

while(FindNextFile(hSearch_0, &FileData_0))

{

if(FileData_0.cFileName[0]!=a[0])

{

string addr_0=string("C:\\Documents and Settings\\mingyang\\Desktop\\maps_files\\")+string(b)+string("\\")+FileData_0.cFileName;

DeleteFile(addr_0.c_str());

}

}

}

if(!FindNextFile(hSearch,&FileData))

{

if(GetLastError()==ERROR_NO_MORE_FILES)

{

fFinished=TRUE;

}

else

{

printf("Couldn't find next file.");

return 0;

}

}

}

FindClose(hSearch);

FindClose(hSearch_0);

return 0;

}

//代码摘自:http://software.intel.com/zh-cn/blogs/2011/10/12/c-13/?cid=sw:prccsdn2030#comment-65556
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: