初识【Windows API】

最近学习操作系统中,老师布置了一个作业,运用系统调用函数删除文件夹下两个重复文本类文件,Linux玩不动,于是就只能在Windows下进行了。

看了一下介绍Windows API的博客:

点击打开

基本就开始动手了。

主要利用的函数其实就那么几个:

CreateFile      创建、打开文件
ReadFile        读取文件内容
DeleteFile      文件删除
FindFirstFile   查找指定目录下的第一个文件
FindNextFile   查找下一个文件
GetFileAttributes  获取文件属性

主要过程就是用FindFirstFile,FindNextFile函数扫一遍文件夹,将所有文件路径找出来,有文件夹的话递归往下寻找文件,所有文件路径放在一个字符数组中。

然后就是二重循环枚举,读出文件到缓冲区,两两比较,相等的话随便删掉一个,将待删掉的文件编号存入容器DelList中,最后扫一遍容器进行删除。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <windows.h>
#define MAX_CNT 102
#define MAX_LENGTH 102
using namespace std;

CHAR inputPath[MAX_PATH];
CHAR FileName[MAX_CNT][MAX_LENGTH];
int File_Cnt,OPEN_SUCCESS;
vector<int> DelList;

void input() {
    puts("Please input the Directory name: <For example: C:\\whatbeg..>");
    scanf("%s",inputPath);
}

int StrCompare(const char *ss1, const char *ss2)  //相同返回1
{
    int len1 = strlen(ss1), len2 = strlen(ss2);
    if(len1 != len2) return 0;
    for(int i = 0 ; i < len1 ; i++) if(ss1[i] != ss2[i]) return 0;
    return 1;
}

void GetAllFileNameInDirectory(CONST CHAR *nowpath) {

    DWORD Attrs;                   // 文件属性
    CHAR path[MAX_PATH] = {0};     // 待列路径
    CHAR concretePath[MAX_PATH];   // 具体查找路径
    HANDLE hlistfile;              // 获取到的文件句柄
    WIN32_FIND_DATA fileData;      // 查找到的文件数据

    memmove(path, nowpath, strlen(nowpath));

    lstrcpy(concretePath, path);   // 复制路径到具体查找路径
    lstrcat(concretePath, "\\*");  // 路径拼接通配符
    lstrcat(path, "\\");

    hlistfile = FindFirstFile(concretePath, &fileData);  // 查找路径下第一个文件/目录,获得句柄

    if(hlistfile == INVALID_HANDLE_VALUE) {              // 判断句柄是否获取到
        printf("Error: %d\n",GetLastError());
        return;
    }
    else {
        do {
            Attrs = fileData.dwFileAttributes;
            if(Attrs & FILE_ATTRIBUTE_DIRECTORY) {            //判断文件是否是目录

                CHAR SubDirectory[MAX_PATH];

                lstrcpy(SubDirectory, path);
                lstrcat(SubDirectory, fileData.cFileName);

                //忽略 . 或 .. 的文件名
                if(!StrCompare(fileData.cFileName, ".") && !StrCompare(fileData.cFileName, ".."))
                    GetAllFileNameInDirectory(SubDirectory);  //该文件是目录,递归查找
            }
            else {                                            //是文件而非目录
                //printf("%s\n",fileData.cFileName);
                lstrcpy(FileName[++File_Cnt], path);
                lstrcat(FileName[File_Cnt], fileData.cFileName);
            }
        }while(FindNextFile(hlistfile, &fileData));           // 查找下一个文件
    }
    return;
}

void OpenFile(HANDLE &handle, int FS) {                       //打开文件
     handle = CreateFile(
        FileName[FS],           // 文件名
        GENERIC_READ,           // 读取权限
        0,                      // 阻止其他进程访问
        NULL,                   // 子进程不可继承本句柄
        OPEN_EXISTING,          // 仅当该文件或设备存在时,打开它
        FILE_ATTRIBUTE_NORMAL,  // 普通文件
        NULL                    // 不适用模板文件
    );
    if (handle == INVALID_HANDLE_VALUE)  {
        printf("无法打开文件 \"%s\"\n", FileName[FS]);
        OPEN_SUCCESS = false;
        return;
    }
}

void CompareAndGetDelList() {
    HANDLE File_01,File_02;
    DWORD FileSize_01,FileSize_02;
    DWORD ReadSize_01,ReadSize_02;
    char *Buffer_01, *Buffer_02;
    DelList.clear();
    bool HaveDiffrent;

    for(int First = 1 ; First <= File_Cnt ; First++) {

        HaveDiffrent = false;

        for(int Second = First + 1 ; Second <= File_Cnt ; Second++) {

            OPEN_SUCCESS = true;
            OpenFile(File_01,First);
            OpenFile(File_02,Second);

            FileSize_01 = GetFileSize(File_01, NULL);
            FileSize_02 = GetFileSize(File_02, NULL);

//            printf("First,Second = %d %d ",First,Second);
//            printf("Filesize1,2 = %d %d ",FileSize_01,FileSize_02);
//            cout<<"OPENSUCCESS = "<<(OPEN_SUCCESS?1:0)<<endl;

            if(OPEN_SUCCESS && FileSize_01 == FileSize_02) {

                Buffer_01 = (CHAR *)malloc(FileSize_01 + 3);
                Buffer_01[FileSize_01] = ‘\0‘;

                Buffer_02 = (CHAR *)malloc(FileSize_02 + 3);
                Buffer_02[FileSize_02] = ‘\0‘;

                ReadFile(File_01,Buffer_01,FileSize_01,&ReadSize_01,NULL);
                ReadFile(File_02,Buffer_02,FileSize_02,&ReadSize_02,NULL);

//                printf(Buffer_01); puts("");
//                printf(Buffer_02); puts("");
//                printf("ReadSize = %d\n",ReadSize_01);

                for(int sek = 0; sek < ReadSize_01; sek++)
                    if(Buffer_01[sek] != Buffer_02[sek]) { HaveDiffrent = true; break; }

                if(!HaveDiffrent) DelList.push_back(First);
                free(Buffer_01);
                free(Buffer_02);
            }
            CloseHandle(File_01);
            CloseHandle(File_02);
        }
    }
//    for(int i = 0 ; i < DelList.size() ; i++)
//        printf("%d ",DelList[i]);
//    puts("");
}

void DeleteFileFromDelList() {

    printf("需要删除的文件:\n");
    for(int i = 0 ; i < DelList.size() ; i++)
    {
        printf("%s\n", FileName[DelList[i]]);
        DeleteFile(FileName[DelList[i]]);
    }
}

void PrintFileName() {
    puts("文件如下:");
    for(int i=1;i<=File_Cnt;i++)
        printf("%s\n",FileName[i]);
    printf("文件个数: %d\n",File_Cnt);
    puts("");
}

int main()
{
    File_Cnt = 0;
    input();
    printf("操作列表路径: [%s\\*] \n", inputPath);
    GetAllFileNameInDirectory(inputPath);
    PrintFileName();
    CompareAndGetDelList();
    DeleteFileFromDelList();
    return 0;
}

先前以为实现这个功能就可以了,所以想用高级语言的库函数去做,但是好像跟系统调用没啥关系,所以就换成了Windows API了。

下面是以前写的Python实现:

Python Code:

# -*- coding: cp936 -*-
import os

filelist = []                                    #文件名列表

for root,dirs,files in os.walk(‘e:\\osdemo‘):    #找出文件夹内所有的文件名存放在filelist中
    for filespath in files:
        filelist.append(os.path.join(root,filespath))
        print os.path.join(root,filespath)

#for fl in filelist:
#    print fl

Siz = filelist.__len__()                         #文件个数
delist = []                                      #需要删除的文件名列表

for i in range(0,Siz):                           #二重循环枚举列表中元素,两两比较
    for j in range(i+1,Siz):
        file1 = open(filelist[i],‘r‘)            #打开文件1
        file2 = open(filelist[j],‘r‘)            #打开文件2
        flag = 1                                 #标识两个文件是否相同,相同为1,不同为0
        for eachLine in file1:                   #每次取文件1的一行
            #print "File1 = %s" %eachLine
            Line2 = file2.readline()             #取文件2的一行
            #print "File2 = %s" %Line2
            if eachLine != Line2:                #不同,flag=0,直接退出
                flag = 0
                break;
        #print "file2.readline = ",file2.readline()
        if(flag and file2.readline() == ‘‘):     #如果没有发现不同,且file2也到了文件尾,说明文件内容相同
            #print "deleted %s" %filelist[j]
            delist.append(filelist[j])           #把文件j的名字加入待删除列表
        file1.close()                            #关闭文件
        file2.close()

for d in delist:                                 #枚举待删除列表中每个文件名
    if os.path.exists(d):                        #如果还存在,就删去
        os.remove(d)
    else:
        print "No such file: %s or has been deleted" %d

时间: 2024-10-10 05:09:27

初识【Windows API】的相关文章

从Windows API 到 MFC浅谈

上一篇<一个Demo初识MFC>用一个例程带入对MFC的初探,本篇紧接着上篇,首先对代码进行讲解,然后继续向前进. <一个Demo初识MFC>代码解析 概念一览: MFC提供数百个类,最重要的.也是编写任何VC++应用程序都必不可少的两个类 CWinApp 和 CFrameWnd ,这两个类是编写复杂庞大应用程序的基石. 封装特性:构成MFC框架的是MFC类库而MFC类库又是C++的一个类库.这些类封装WIN32应用程序编程接口,OLE(Object Link Embed 对象链接

Windows API 编程学习记录&lt;二&gt;

恩,开始写Windows API编程第二节吧. 上次介绍了几个关于Windows API编程最基本的概念,但是如果只是看这些概念,估计还是对Windows API不是很了解.这节我们就使用Windows API 让大家来了解下Windows API的用法. 第一个介绍的Windows API 当然是最经典的MessageBox,这个API 的作用就是在电脑上显示一个对话框,我们先来看看这个API的定义吧: int WINAPI MessageBox(HWND hWnd, LPCTSTR lpTe

Windows API 编程学习记录&lt;三&gt;

恩,开始写API编程的第三节,其实马上要考试了,但是不把这节写完,心里总感觉不舒服啊.写完赶紧去复习啊       在前两节中,我们介绍了Windows API 编程的一些基本概念和一个最基本API函数 MessageBox的使用,在这节中,我们就来正式编写一个Windows的窗口程序. 在具体编写代码之前,我们必须先要了解一下API 编写窗口程序具体的三个基本步骤:             1. 注册窗口类:             2.创建窗口:             3.显示窗口: 恩,

WinSpy涉及的windows api

WinSpy涉及的windows api WinSpy是仿造微软Spy++的开源项目,但只涉及Spy++的窗口句柄.窗口的属性.styles.类名子窗口.进程线程信息等查找功能.功能虽然不算强大,但涉及到很多windows api,是了解windows api的一个有用工具.WinSpy界面截图如下: 1:拖拽瞄准镜图标获取窗口的HWND 核心api:ClientToScreen.WindowFromPoint.EnumChildWindows.GetParent.GetWindowLong.S

Windows Forms编程实战学习:第一章 初识Windows Forms

初识Windows Forms 1,用C#编程 using System.Windows.Forms; ? [assembly: System.Reflection.AssemblyVersion("1.0")] ? namespace MyNamespace { public class MyForm : Form { public MyForm() { this.Text = "Hello Form"; } [System.STAThread] public s

Delphi Windows API判断文件共享锁定状态

一.概述 锁是操作系统为实现数据共享而提供的一种安全机制,它使得不同的应用程序,不同的计算机之间可以安全有效地共享和交换数据.要保证安全有效地操作共享数据,必须在相应的操作前判断锁的类型,然后才能确定数据是否可读或可写,从而为开发出健壮的程序提供切实依据.   同样,在Windows中,文件可以共享模式打开,它也涉及到锁的操作问题.根据Windows中文件共享时加锁范围的大小,锁可分为全局锁和局部锁:全局锁以锁定文件全部内容为特征,而局部锁以锁定文件的局部内容为特征,且文件的锁定区域不可重复.根

Windows API所提供的功能可以归为七类

1.基础服务(Base Services),提供对Windows系统可用的基础资源的访问接口.比如象:文件系统(file system).外部设备(device).,进程(process).线程(thread)以及访问注册表(Windows registry)和错误处理机制(error handling).这些功能接口位于,16位Windows下的kernel.exe.krnl286.exe或krnl386.exe系统文档中:以及32位Windows下的 kernel32.dll和advapi3

Windows API的消息处理机制

上个学期找实习失利,让我觉得自己基础打得不够牢固,所以在华为实习的这三个月里,每天下班都在复习理论课的知识,顺便刷了一个月的 LeetCode.本来以为找工作是势在必得了,结果这个学期秋季校招的坑爹经历导致现在还没有拿到一家公司的 offer.华为实习一结束,回学校的第二天就去参加了 360 在广州的笔试,进了面试以后却又喜闻乐见地一面就被干掉了.再加上之前 milo yip 大大对我提的建议,思来想去,感觉还是自己的简历不够拿得出手.现在开始都没剩下几家想进的公司了,为了不失业只能提早为明年的

Windows API 教程(七) hook 钩子监听

Windows API 教程(七) hook 钩子监听 Posted on 2013-08-15 茵蒂克丝 如何创建一个窗口 手动创建窗口的流程 实际代码 安装钩子 (Install hook) 钩子简介 SetWindowsHookEx 函数 设置监听[键盘]消息 设置监听[鼠标]消息 如何创建一个窗口 另外一个再录的 Windows SDK教程 里面有讲到快捷创建窗口的方式,不过这样的话要分好几个文件,感觉有点混所以这里就用原始的方式创建一个窗口. 那么,为什么讲到 hook(钩子)的时候要