初识【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 ;
for(int i = ; i < len1 ; i++) if(ss1[i] != ss2[i]) return ;
return ;
} void GetAllFileNameInDirectory(CONST CHAR *nowpath) { DWORD Attrs; // 文件属性
CHAR path[MAX_PATH] = {}; // 待列路径
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, // 读取权限
, // 阻止其他进程访问
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 = ; First <= File_Cnt ; First++) { HaveDiffrent = false; for(int Second = First + ; 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 + );
Buffer_01[FileSize_01] = '\0'; Buffer_02 = (CHAR *)malloc(FileSize_02 + );
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 = ; 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 = ; i < DelList.size() ; i++)
{
printf("%s\n", FileName[DelList[i]]);
DeleteFile(FileName[DelList[i]]);
}
} void PrintFileName() {
puts("文件如下:");
for(int i=;i<=File_Cnt;i++)
printf("%s\n",FileName[i]);
printf("文件个数: %d\n",File_Cnt);
puts("");
} int main()
{
File_Cnt = ;
input();
printf("操作列表路径: [%s\\*] \n", inputPath);
GetAllFileNameInDirectory(inputPath);
PrintFileName();
CompareAndGetDelList();
DeleteFileFromDelList();
return ;
}
效果测试
1.新建一个文件夹e:\\osdemo:
2.在其中新建一些文本文档:
hello 文件夹内容如下所示:
其中 王美丽.txt 和 汪美丽.txt , 蓝玉.txt 和 徐达.txt , Apple.txt 和 hello\Apple.txt 的内容是一致的,将会被去重。
3.执行程序,输入目标文件夹位置:
4.执行结果:
5.需要删除其中三个文件
6.再次返回文件管理器,发现三个文件已被删去:
7.再执行,不再有重复文件:
先前以为实现这个功能就可以了,所以想用高级语言的库函数去做,但是好像跟系统调用没啥关系,所以就换成了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
初识【Windows API】--文本去重的更多相关文章
- Windows API 函数列表 附帮助手册
所有Windows API函数列表,为了方便查询,也为了大家查找,所以整理一下贡献出来了. 帮助手册:700多个Windows API的函数手册 免费下载 API之网络函数 API之消息函数 API之 ...
- 学习之路三十九:新手学习 - Windows API
来到了新公司,一开始就要做个程序去获取另外一个程序里的数据,哇,挑战性很大. 经过两周的学习,终于搞定,主要还是对Windows API有了更多的了解. 文中所有的消息常量,API,结构体都整理出来了 ...
- Windows API Finishing
input { font-size: 14px; height: 26px } td { border-style: none; border-color: inherit; border-width ...
- Windows API 调用示例
Ø 简介 本文主要记录 Windows API 的调用示例,因为这项技术并不常用,属于 C# 中比较孤僻或接触底层的技术,并不常用.但是有时候也可以借助他完成一些 C# 本身不能完成的功能,例如:通 ...
- 《随机出题软件》&《随机分队软件》源码(Windows API)
1 引言 1.1 编写目的: 为了对院级活动<最强大脑>提供软件支持,同时为了练习使用windows API. 1.2 项目背景: 来自计算机学院学生会信息部指派的任务,规定时间完成软件的 ...
- Windows API函数大全(完整)
Windows API函数大全,从事软件开发的朋友可以参考下 1. API之网络函数 WNetAddConnection 创建同一个网络资源的永久性连接 WNetAddConnection2 创建同一 ...
- [windows菜鸟]Windows API函数大全(完整)
Windows API函数大全,从事软件开发的朋友可以参考下 1. API之网络函数 WNetAddConnection 创建同一个网络资源的永久性连接 WNetAddConnection2 创建同一 ...
- WINDOWS API 大全(二)
9. API之设备场景函数 CombineRgn 将两个区域组合为一个新区域CombineTransform 驱动世界转换.它相当于依顺序进行两次转换CreateCompatibleDC 创建一个与特 ...
- WINDOWS API 大全(一)
1. API之网络函数 WNetAddConnection 创建同一个网络资源的永久性连接 WNetAddConnection2 创建同一个网络资源的连接 WNetAddConnection3 创建同 ...
随机推荐
- canvas孙悟空脚踩白云今年是猴年
效果查看:http://hovertree.com/texiao/html5/30/ 使用HTML5的canvas画的孙悟空,CSS3画的白云飘飘. 刚擒住了几个妖 又降住了几个魔 魑魅魍魉怎么他就这 ...
- 【发布】工业串口和网络软件通讯平台(SuperIO v2.2.4)
SuperIO 下载:本站下载 百度网盘 更新说明: 1.修复无法把数据输出给IAppService的问题,以及无法触发删除操作事件. 2.侦听端口,可以设置. 3.设备接口,增加Object属性,方 ...
- IOS应用内存释放机制
这是由iOS系统管理决定的,但APP退出在后台后,只有10秒的持续运行时间,然后暂停.但该APP还在内存中,当出现内存警告,也就是别的APP要运行,而此时内存又不足的情况下,系统会回收停在后台APP所 ...
- 取消IE默认下载工具为迅雷
需求:企业访问内部WEB系统下载文件时,IE默认下载工具设置为迅雷,则弹出迅雷下载框.现需要直接弹出IE下载保存框. 方案:打开迅雷,进行撤销默认下载工具. 1.迅雷5: 1.1. 打开迅雷下载工具 ...
- CSS实现弹出导航菜单
查看实际效果:http://keleyi.com/a/bjac/vksd7321.htm 完整代码,保存在html文件打开也可看到效果: <!DOCTYPE html PUBLIC " ...
- 【小贴士】关于transitionEnd/animate的一个有趣故事
前言 在很久之前,我们项目有一个动画功能,功能本身很简单,便是典型的右进左出,并且带动画功能 以当时来说,虽然很简单,但是受限于框架本身的难度,就直接使用了CSS3的方式完成了功能 当时主要使用tra ...
- easyui弹出层在最顶层显示跳出iframe框架通用javascript代码
有时候我们用easyui在后台框架中弹框的时候,总是显示在框架页面里面而不是整个系统框架的上面,看着有些不太乐意. dialog = function (opts) { var query = par ...
- plist的读取和写入
// 从plist中读取数组数据 let arrPath = Bundle.main.path(forResource: "ArrayPList", ofType: "p ...
- IOS开发基础知识--碎片3
十二:判断设备 //设备名称 return [UIDevice currentDevice].name; //设备型号,只可得到是何设备,无法得到是第几代设备 return [UIDevice cur ...
- MyBatis Generator作为maven插件自动生成增删改查代码及配置文件例子
什么是MyBatis Generator MyBatis Generator (MBG) 是一个Mybatis的代码生成器,可以自动生成一些简单的CRUD(插入,查询,更新,删除)操作代码,model ...